如何从等待的异步方法中捕获C#异常?

时间:2012-11-07 09:43:02

标签: c# .net asynchronous exception-handling async-await

我基本上想知道在C#中我应该如何从通过await关键字等待的异步方法中捕获异常。例如,考虑以下小型控制台程序,其中最重要的是包含一个名为AwaitSync的方法。 AwaitSync调用TestAsync,它返回一个在执行时抛出异常的Task。我尝试在AwaitAsync中捕获异常,但它未处理

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"); });
    }
}

我应该如何从TestAsync返回的任务中捕获异常?虽然这个例子是一个控制台程序,但我的实际问题是在ASP.NET MVC / Web API的上下文中。

修改 事实证明异常被抓住了,由于技术原因我在终端关闭之前没有注意到“Exception caught”消息。无论如何,Jon Skeet的回答对我理解await和异常处理非常有价值。

1 个答案:

答案 0 :(得分:10)

await表达式生成的代码将调用与GetResult()返回的TaskAwaiter相关联的Task上的TestAsync

GetResult会注意到该任务出现故障,从任务中的AggregateException获取第一个异常,并抛出该异常。

最终结果是你的catch块将捕获你的任务中抛出的异常 - 但是如果等待具有多个异常的任务,你将只看到第一个,除非你采取特殊的行动(有各种方法)。

当你声称异常实际上没有处理时,你的代码中似乎有一些东西,而不是你所展示的内容 - 因为你给出的代码肯定会起作用,对我来说也是如此。