When catching an Exception
, you have to make sure it is exactly the exception being thrown. When using Task.Run
or Task.Factory.Startnew
and generally involving an exception being thrown from a Task
(unless the task is being awaited with the await
keyword), the outer exception you're dealing with is an AggregateException
, because a Task
unit may have child tasks which may also throw exceptions.
From Exception Handling (Task Parallel Library):
Unhandled exceptions that are thrown by user code that is running
inside a task are propagated back to the joining thread, except in
certain scenarios that are described later in this topic. Exceptions
are propagated when you use one of the static or instance Task.Wait or
Task.Wait methods, and you handle them by enclosing the call
in a try-catch statement. If a task is the parent of attached child
tasks, or if you are waiting on multiple tasks, then multiple
exceptions could be thrown. To propagate all the exceptions back to
the calling thread, the Task infrastructure wraps them in an
AggregateException instance. The AggregateException has an
InnerExceptions property that can be enumerated to examine all the
original exceptions that were thrown, and handle (or not handle) each
one individually. Even if only one exception is thrown, it is still
wrapped in an AggregateException.
So, in order to deal with that, you have to catch AggregateException
:
try
{
//do something
}
catch (TimeoutException t)
{
Console.WriteLine(t);
}
catch (TaskCanceledException tc)
{
Console.WriteLine(tc);
}
catch (AggregateException ae)
{
// This may contain multiple exceptions, which you can iterate with a foreach
foreach (var exception in ae.InnerExceptions)
{
Console.WriteLine(exception.Message);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
AggregationException
thrown from aTask
object? show us the throwing call – Willowwillowy