Reputation: 67987
I'm basically wondering how I should, in C#, catch exceptions from asynchronous methods that are waited on through the await
keyword. Consider for example the following small console program, which most importantly contains a method called AwaitSync
. AwaitSync
calls TestAsync
, which returns a Task that when executed throws an exception. I try to catch the exception in AwaitAsync
, but it goes unhandled.
class Program
{
static void Main(string[] args)
{
AwaitAsync();
Console.ReadKey();
}
static async Task AwaitAsync()
{
try
{
await TestAsync();
}
catch (Exception)
{
Console.WriteLine("Exception caught");
}
}
static Task TestAsync()
{
return Task.Factory.StartNew(() => { throw new Exception("Test"); });
}
}
How am I supposed to go about catching the exception from the Task returned by TestAsync
? While this example is a console program, my real life problem is within the context of of ASP.NET MVC / Web API.
EDIT:
Turns out the exception is getting caught, for technical reasons I just didn't notice the 'Exception caught' message before the terminal closed. In any case, Jon Skeet's answer was very valuable to my understanding of await
and exception handling.
Upvotes: 5
Views: 536
Reputation: 1500065
The code generated for the await
expression will call GetResult()
on the TaskAwaiter
associated with the Task
returned by TestAsync
.
GetResult
will notice that the task is faulted, fetch the first exception from the AggregateException
within the task, and throw that.
The net result is that your catch block will catch the exception thrown in your task - but if you await a task which has multiple exceptions, you'll only see the first one unless you take special actions (there are various approaches to this).
As you're claiming the exception actually goes unhandled, it seems there's something in your code other than what you're showing - as the code you've given should certainly work, and does for me.
Upvotes: 10