I'm trying to run the following code:
class Program
{
static void Main(string[] args)
{
var task = Task.Factory.StartNew(() =>
{
throw new ApplicationException("message");
});
try
{
task.ContinueWith(t => Console.WriteLine("End"));
}
catch (AggregateException aex)
{
Console.Write(aex.InnerException.Message);
}
}
}
I expected that the Exception
would be caught in the following location:
catch (AggregateException aex)
{
Console.Write(aex.InnerException.Message);
}
But this is not happening. Why is this so?
You're just printing out the task
- which won't even have completed yet.
Printing out the task doesn't wait for it to complete, or try to fetch the value.
If you change your code to:
try
{
task.Wait();
}
... then I'd expect it to catch the exception.
(I was previously using Task<T>.Result
, but I notice this is a task with no return value, so it would just be the non-generic Task
.)
The way Task
works, the code that ends up calling the delegate you pass to StartNew
will be caught, eventually, and the Exception
will be stored in an instance field of the task. That exception can be inspected by looking at the task.Exception
property. The line Console.WriteLine(task)
is just calling task.ToString
internally. That method won't result in the exception being thrown or re-thrown.
However, under certain circumstances the exception that is caught will be re-thrown. Two examples are when accessing Result
and calling Wait
, as well as when you await
a task in C# 5.0.
The following code:
try
{
task.Wait();
}
catch (AggregateException aex)
{
Console.Write(aex.InnerException.Message);
}
Will result in the stored exception being re-thrown and the exception message will be printed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With