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.

Full example code