[Info] Asynchronous Programming: Exception Handling

Apr 5, 2014 at 12:22 PM
Edited May 14, 2016 at 7:28 PM

This article has been moved to GitHub!

Unhandled exceptions thrown in a task are propagated back via the Task object. By using the “await” keyword the exception can be catched simply by a try/catch block. The intention with “await” was to simplify the asynchronous programming in a way that it feels like calling synchronous (blocking) methods. But in some cases this might be an over-simplification because it can happen that a task faults with more than one Exception. This could happen with combinators like the Task.WhenAll method. The Task itself stores all Exceptions in a Wrapper: The AggregateException. If you are programming against the Task directly then you are able to investigate all Exceptions.

Handle all Exceptions thrown by a Task:
Task task = Task.Factory.StartNew(() => { throw new UnauthorizedAccessException(); }); 
catch (AggregateException ex)
    ex.Handle(x =>
        if (x is UnauthorizedAccessException)
            // Handle this exception...
            return true;
        // Other exceptions will not be handled here.
        return false;
However, in my experience the design decision for this exception handling simplification was a good one. Until now I had never the need to handle all exceptions. It was sufficient for my scenarios to investigate just the first one because it was mostly the only one.

In some scenarios it is better to call an asynchronous method in a synchronous (blocking) way. This might be because we know that the method never takes much time and it would need a lot code to ensure that the user cannot continue to work with the user interface (e.g. avoid re-entrance or race conditions). We can do this by calling the Task.Wait method. But then we have to write the more complex exception handling code which investigates all inner exceptions of the AggregateException (see code snipped above).

If we would like to write the exception handling code in the same way as we would do with the “await” keyword then we have to call the following method:
task.GetAwaiter().GetResult();    // instead of task.Wait();
Further readings
  1. MSDN Exception Handling (Task Parallel Library)
  2. MSDN Blog Task Exception Handling in .NET 4.5