The following forum(s) have migrated to Microsoft Q&A (Preview): Developing Universal Windows apps!
Visit Microsoft Q&A (Preview) to post new questions.

Learn More

 locked
[UWP] Using deferral on processing dropped files RRS feed

  • Question

  • Hi,

    In an app where files can be dropped, the drop handler receives a DragEventArgs object. But it seems the deferral in this handler is ignored, because in the source app, where the draging was started, the handler for the DragStartingEventArgs.Data.OperationCompleted event is called before the deferral in the destination app is completed.

    If I want to ask the user, if he really wants to import the dropped data, and he waits a few seconds before clicking on the answer, he will get a FileNotFoundException because in the OperationCompleted handler of the source app the prepared file has already been deleted.

    The drop handler runs in the GUI thread. So I cannot call the Dispatcher for opening the MessageDialog and wait with Task.Wait() for the users answer, but have to use await.

    Does someone have a clue, how I can solve this issue?

    Source:

    private async void Data_OperationCompleted(DataPackage sender, OperationCompletedEventArgs args)
    {
    	foreach (StorageFile file in DraggedFiles)
    		await file.DeleteAsync();
    	DraggedFiles.Clear();
    }

    Destination:

    private async void Page_Drop(object sender, DragEventArgs e)
    {
    	e.Handled = true;
    
    	DragOperationDeferral	deferral = e.GetDeferral();
    
    	try
    	{
    		MessageDialog	dlg = new MessageDialog("Do you want to import the dropped files?");
    
    		dlg.Commands.Add(new UICommand("Yes"));
    		dlg.Commands.Add(new UICommand("No"));
    		if (await dlg.ShowAsync() != dlg.Commands[0])
    			return;
    
    		IReadOnlyList<IStorageItem>	droppedItems = await e.DataView.GetStorageItemsAsync();
    
    		await ProcessDroppedItems(droppedItems);
    	}
    	finally
    	{
    		deferral.Complete();
    	}
    }

    Best Regards,
    Heiko
    Friday, November 15, 2019 5:36 PM

Answers

  • The question that comes to my mind is whether DragEventArgs.GetDeferral() within a drop handler has any meaning. If yes, which one?

    Maybe it is not right that I delay the processing of the dropped file in the drop handler with a MessageDialog.

    The sample doesn't help me with a dropped to be processed file.

    Best Regards,
    Heiko

    GetDeferral is necessary, We need to take the deferral as the source will read drag item which we cannot set synchronously.

    By the way, We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!


    "Developing Universal Windows apps" forum will be migrating to a new home on Microsoft Q&A (Preview)!
    We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!
    For more information, please refer to the sticky post.


    Wednesday, November 20, 2019 1:29 AM
  • OK, I see that I have to use a deferral in the drop handler, if the source app deletes the file in the OperationCompleted handler.
    With a deferral, I have about 500 ms to read the file. If the file is too big, I will get an IOException after 500 ms.

    That seems to be the design.

    • Marked as answer by Heiko65456465 Friday, November 22, 2019 3:50 PM
    Friday, November 22, 2019 3:50 PM

All replies

  • Hi,

    I tried your code, unfortunately, we could not repro your issue. For my testing, I could get IStorageItem in Page_Drop event handler. I check this DragStartingEventArgs.Data.OperationCompleted, But I could not find any related code on above. could you share a mini sample for us, and I will edit base on your demo.


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, November 18, 2019 3:19 AM
  • Hi NicoZhu-MSFT,

    Thank you for the reply. The dropped file should be opened and read, then you get an exception.

    I uploaded a VS 2017 solution with 2 projects here. The project DragFile should be startet with F5, then you can see in the debug output window when the OperationCompleted handler is called.

    Perhaps it's by design that OperationCompleted is early called. But how can the source app ensure that the other app can read the dropped file and how to detect then that the generated file can be deleted?

    Best Regards,
    Heiko

    Monday, November 18, 2019 6:54 PM
  • hi Heiko65456465,    

    For my testing, the  OperationCompleted  even will trigger when the mouse left button release , it's normal behavior,

    But how can the source app ensure that the other app can read the dropped file and how to detect then that the generated file can be deleted?

    You could get dropped file within Drop even that triggered from the target element. And The Drop even will be triggered before the source element  OperationCompleted . 

    For example:

    <Grid>
        <TextBlock
            CanDrag="True"
            DragStarting="TextBlock_DragStarting"
            FontSize="20"
            Text="Click &amp; drag"
            />
        <TextBox
            Width="100"
            Height="100"
            Margin="100"
            AllowDrop="True"
            DragEnter="TextBox_DragEnter"
            Drop="TextBox_Drop"
            />
    </Grid>
    
    

    Code Behind

    private void TextBox_Drop(object sender, DragEventArgs e)
    {
        Debug.WriteLine("TextBox_Drop()");
    }
    
    private void TextBox_DragEnter(object sender, DragEventArgs e)
    {
        e.AcceptedOperation = (e.DataView.Contains(StandardDataFormats.StorageItems)) ? DataPackageOperation.Copy : DataPackageOperation.None;
    }
    For more details please refer official code sample.


    "Developing Universal Windows apps" forum will be migrating to a new home on Microsoft Q&A (Preview)!
    We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!
    For more information, please refer to the sticky post.


    Tuesday, November 19, 2019 7:32 AM
  • The question that comes to my mind is whether DragEventArgs.GetDeferral() within a drop handler has any meaning. If yes, which one?

    Maybe it is not right that I delay the processing of the dropped file in the drop handler with a MessageDialog.

    The sample doesn't help me with a dropped to be processed file.

    Best Regards,
    Heiko

    Tuesday, November 19, 2019 2:31 PM
  • The question that comes to my mind is whether DragEventArgs.GetDeferral() within a drop handler has any meaning. If yes, which one?

    Maybe it is not right that I delay the processing of the dropped file in the drop handler with a MessageDialog.

    The sample doesn't help me with a dropped to be processed file.

    Best Regards,
    Heiko

    GetDeferral is necessary, We need to take the deferral as the source will read drag item which we cannot set synchronously.

    By the way, We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!


    "Developing Universal Windows apps" forum will be migrating to a new home on Microsoft Q&A (Preview)!
    We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A (Preview)!
    For more information, please refer to the sticky post.


    Wednesday, November 20, 2019 1:29 AM
  • OK, I see that I have to use a deferral in the drop handler, if the source app deletes the file in the OperationCompleted handler.
    With a deferral, I have about 500 ms to read the file. If the file is too big, I will get an IOException after 500 ms.

    That seems to be the design.

    • Marked as answer by Heiko65456465 Friday, November 22, 2019 3:50 PM
    Friday, November 22, 2019 3:50 PM