Category Archives: Asynchronous

C# quick tip: does exception handling work with async method calls?

The short answer is, yes… but.

Say you’ve defined some async method:

public async Task<bool> MyAsyncMethod() {

    // Location A: some code here

    var result = await SomeOtherAsyncMethod();

    // Location B: some more code here

    if (someCondition) {
        throw new SomeException();
    }

    return result;
}

How can you call MyAsyncMethod in a try-catch block so you can catch SomeException?

Here’s what you DON’T do:

try {

    // Location C: yet more code here

    MyAsyncMethod();

    // Location D: and even more code

} catch (SomeException ex) {

    // Location E: exception handling code

}

The problem is the call to MyAsyncMethod (highlighted) doesn’t await its return. As soon as MyAsyncMethod has finished executing the code at location A and hits the line that calls SomeOtherAsyncMethod, control returns to the code after the call to MyAsyncMethod (location D). It then passes out of the try-catch block before the code at location B has chance to execute.

Thus, if SomeException is thrown, it won’t be caught. Since there’s now no handler for it, your app is going down…

Oops, something's gone wrong.

(The specifics of what actually happens will depend on the type of app and, sorry desktop IE, I don’t mean to pick on you.)

To catch the exception, you need to await the return of MyAsyncMethod:

try {

    // Location C: yet more code here

    await MyAsyncMethod();

    // Location D: and even more code

} catch (SomeException ex) {

    // Location E: exception handling code

}

Or, if you need its return value:

var result = await MyAsyncMethod(); // etc.

Either way control will not return to your calling code, continuing at location D, until MyAsyncMethod has completed. If MyAsyncMethod throws SomeException, it will be caught and handled by the code at location E – as expected.

IMPORTANT: there is no blocking here so your app will not become unresponsive whilst MyAsyncMethod runs.

There’s a lot of compiler magic* The compiler does a lot of work for you to ensure this works seamlessly. It also uses some support types in the framework itself. This means you can keep your code nice and straightforward.

If you’d like to know more about how async compilation works, check out http://weblogs.asp.net/dixin/archive/2012/11/02/understanding-c-async-await-1-compilation.aspx.

*It’s clever, but it’s absolutely not magic. Rather, it’s awesome engineering.