locked
Need help to understand an await and async situation

    Question

  • I have the following code:

    MainPage()
    {
       Debug.WriteLine("A");
       FooAsync();
       Debug.WriteLine("B");
    }
    
    private async Task FooAsync()
    {
       try
       {
          StorageFolder sf= await ApplicationData.Current.LocalFolder.GetFolderAsync("Foo");
       }
       catch(Exception ex)
       {
          Debug.WriteLine("Async");
       }
    }

    How come I get:

    A
    Async
    B

    instead of:

    A
    B
    Async

    I thought await would immediately return the control to MainPage().  That is what await is for partially.  Where is my misunderstanding?


    Hong

    Thursday, April 17, 2014 9:27 PM

Answers

  • It depends what GetFolderAsync is doing.

    If GetFolderAsync checks the existence of something before spinning off a background task to do IO (such to get the item's properties) and the first operation fails - you would see A Async B.

    If the first operation succeeded, but then the IO operation that it did on a background thread failed, you'd see A B Async.


    Darin R.

    • Marked as answer by Hong (MA, USA) Thursday, April 17, 2014 11:28 PM
    Thursday, April 17, 2014 10:36 PM

All replies

  • It depends what GetFolderAsync is doing.

    If GetFolderAsync checks the existence of something before spinning off a background task to do IO (such to get the item's properties) and the first operation fails - you would see A Async B.

    If the first operation succeeded, but then the IO operation that it did on a background thread failed, you'd see A B Async.


    Darin R.

    • Marked as answer by Hong (MA, USA) Thursday, April 17, 2014 11:28 PM
    Thursday, April 17, 2014 10:36 PM
  • Thanks for the response, Darin.

    Here is a quote from the official page explaining await and async:

    "The await operator tells the compiler that the async method can't continue past that point until the awaited asynchronous process is complete. In the meantime, control returns to the caller of the async method."

    This explanation does not put any condition on "In the meantime, control returns to the caller of the async method".  My superficial understanding of this paragraph is that await ensures the return of the control no matter what it is awaited.  However. step 3 of the chart on the page supports your elucidation. The return is conditional. In other words, a labeled async method can effectively be a sync method.


    Hong



    Thursday, April 17, 2014 11:27 PM
  • If the order is important than you should await FooAsync. Otherwise the behavior is non-deterministic.

    In your example the exception could be (and likely is) raised before the Task is returned from GetFolderAsync to be awaited.

    --Rob

    Friday, April 18, 2014 1:12 AM
    Owner
  • In this particular case, I want FooAsync to return as soon as possible for the sake of UI responsiveness.  It took me a while to find that FooAsync() was the culprit for the slowness (1000+ ms in some cases).  I have added "await Task.Delay(10)" at the start of  FooAsync() to solve this problem.

    Hong

    Friday, April 18, 2014 1:49 AM