Six Essential Tips for Async

Tip 1: Async void is for top-level event-handlers only

Download this episode

Download Video

Description

Async Tip #1: Async void is for top-level event-handlers only, and event-like things. Don't use it elsewhere in your code.

Slides are available on Lucian's blog.

Async void is a "fire-and-forget" mechanism: the caller is unable to know when an async void has finished, and the caller is unable to catch any exceptions from it. The only case where this kind of fire-and-forget is appropriate is in top-level event-handlers. Every other async method in your code should return "async Task".

This video goes into some more difficult cases like the Win8 example "overrides async void LoadSettings()". Here you're overriding the method, and can't change the signature, and can't return a Task from it. The solution is to return a Task some other way, like through a field.

The video also talks about the thorny problem of async void lambdas. WHENEVER you see an async lambda, you need to verify whether it will be a void-returning or Task-returning lambda.

 

Embed

Format

Available formats for this video:

Actual format may change based on video formats available and browser capability.

    The Discussion

    • SonOfSam

      Thanks for the video its really good. But I have question,when you mention that when we created a lambda async method we need to always verify that it 's a sub or  task function (I'm VB too) what mechanics do you recommend to validate the out put of the lambda. 

       

    • ljw1004

      Hi SonOfSam! Good question. Let's look at a concrete example.

      Sub f(a As Action)
        a()
        Console.WriteLine("done")
      End Sub
      
      f(Async Function()
          Await Task.Delay(100)
          Console.WriteLine("almost-done")
      End Function)


      In VB, when you write a lambda as "Async Function", then it will always be a Task-returning async. When you write it as "Async Sub" then it will always be a void-returning async.

      But VB has a feature called "delegate relaxation". The compiler realizes that it would be type-safe to just automatically drop the return value of a lambda if needed.

      Well, it would be type-safe, but it's not what we wanted. In this case when the compiler drops the returned Task, then (1) the caller "f" can't know when the lambda has finished, and (2) any exceptions caused by the lambda that were stored in the returned Task will be completely lost to everyone.

      So the guidance for VB is this: when you pass an Async Function lambda, you should verify that the method you're calling does indeed accept Func(Of Task) or some other Task-returning delegate. Just like in C#.


      (Incidentally, if you try to pass an Async Sub lambda to a function, where an Async Function lambda would also have worked, you're almost certainly doing the wrong thing. In this case the compiler gives a warning).

    • SonOfSam

      Thank so much for response

    • HAAM

      Well presented in a very simplified and descriptive way.

    • Ivan

      In the LoadState() discussion, does LoadBitmapAsync() really need to be an async method? It has no await, and it simply returns a Task<BitmapImage> which is later await'ed in the override of OnNavigatedTo(). The method, therefore, is not really async. Thoughts?

    • JohnVFla

      Just learning about these new keywords. Since this is a hard and fast rule, it seems like it might be a good idea to find a way to make the compiler generate either a warning or an error if you use aysnc void in an inappropriate situation.

    • Matthijs​Wessels

      Thanks for the video. I have a question about the first example. What do you suggest I do if the WebRequest.Create(url) call takes quite some time? As I understand, naming the function SendDataAsync indicates that it should only do a small amount of work before returning control to its caller (according to TAP).

    • Barney

      @SonOfSam, Use Refactor -> Extract Method and if it's a Func<Task>, you know it's alright.

    Comments closed

    Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.