Handling Multiple Exceptions from Parallel Tasks in .NET
When executing multiple tasks in parallel where more than one can throw exceptions, you need to catch and handle all exceptions, not just the first one.
The Problem
The exception caught in a catch block when awaiting Task.WhenAll() is only the first exception thrown. All exceptions are actually stored in an AggregateException in the task’s Exception property.
The Solution
var runnersTasks = new List<Task>();
Task compositeTask = null;
try
{
// Run all tasks in parallel
Runners.ForEach(r => runnersTasks.Add(r.RunAsync()));
// Wait for all tasks to complete
compositeTask = Task.WhenAll(runnersTasks);
await compositeTask;
}
catch (Exception)
{
// Rethrow the AggregateException containing all exceptions
throw compositeTask.Exception;
}
The key is storing the Task.WhenAll() reference and rethrowing compositeTask.Exception instead of the caught exception.