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

Play Tip 1: Async void is for top-level event-handlers only
Sign in to queue


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.




Download this episode

The Discussion

  • User profile image

    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. 


  • User profile image

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

    Sub f(a As Action)
    End Sub
    f(Async Function()
        Await Task.Delay(100)
    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).

  • User profile image

    Thank so much for response

  • User profile image

    Well presented in a very simplified and descriptive way.

  • User profile image

    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?

  • User profile image

    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.

  • User profile image

    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).

  • User profile image

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

  • User profile image
    Sudarshan Singh

    The content is very helpful , I have problem with video is pausing too much and why the size of such a small timed video is this much high.

Add Your 2 Cents