In a previous post we discussed about parallel VS serial execution of asynchronous operations. This time instead we’ll see how to properly do exception handling in parallel Tasks.
Let’s suppose you have a bunch of network calls to do, maybe to some microservices. Maybe you’re in an API Gateway and you’re aggregating data.
The calls have no dependencies between each other and can be executed in parallel. So what do you do? You wrap the calls in
Task.WaitAll() or, even better, in
Task.WhenAll(). Something like this:
Task.WhenAll() returns another
Task that can be awaited so we don’t block the current thread. Nice and clean.
Now! Suppose one or all the async operations fail and throw. How would you handle it? Try/catch is a good start:
That works fine, in case you have a single exception. If more than one async operation fails,
Task.WhenAll() will give you visibility only of the first one. That’s one of the main differences with
Task.WaitAll() : this one instead will collect all the exceptions and re-throw an
So what can we do? Go back to
Task.WaitAll() ? Nah.
The trick is to not await directly the call to Task.WhenAll() but to store instead the returned
Task in a variable. In the try/catch block then we can access the
Task.Exception property, which is an
AggregateException, and do whatever we want with its
As usual I’ve pushed a small repo on GitHub. It’s a small dotNET Core console app which runs a bunch of tasks in parallel and shows how to trap the exceptions.