aknuds1
aknuds1

Reputation: 67987

How do I catch in C# an exception from an asynchronous method that is awaited?

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

Answers (1)

Jon Skeet
Jon Skeet

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

Related Questions