AggregateException wraps one or more exceptions produced by a faulted Task. Task.Exception, Wait, and Result expose it when a task fails, with original failures stored in InnerExceptions rather than InnerException. section 3.2.4 section 12.2
Handle the exception according to how the task is observed:
- Inspect task.Exception after checking IsFaulted when you need the aggregate without immediately throwing. section 3.2.4
- Use InnerExceptions to reach the contained failures; do not expect the singular InnerException property to hold them. section 3.2.4
- Expect await to throw the first contained exception instead of AggregateException, even when multiple exceptions are stored. section 12.2
A task with a stored failure
TaskCompletionSource can store a NotSupportedException in a faulted task. Reading Task.Exception reveals AggregateException; awaiting the same task throws NotSupportedException. section 12.2
var tcs = new TaskCompletionSource();
tcs.SetException(new NotSupportedException());
Console.WriteLine("In tasks: "+tcs.Task.Exception.GetType()); #1
try
{
await tcs.Task; #2
}
catch(Exception ex)
{
Console.WriteLine("Thrown: "+ex.GetType()); #3
}
Compare the exception type stored by a task with the exception type propagated by await. section 12.2
