我基本上想知道在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
和异常处理非常有价值。
答案 0 :(得分:10)
为await
表达式生成的代码将调用与GetResult()
返回的TaskAwaiter
相关联的Task
上的TestAsync
。
GetResult
会注意到该任务出现故障,从任务中的AggregateException
获取第一个异常,并抛出该异常。
最终结果是你的catch块将捕获你的任务中抛出的异常 - 但是如果等待具有多个异常的任务,你将只看到第一个,除非你采取特殊的行动(有各种方法)。
当你声称异常实际上没有处理时,你的代码中似乎有一些东西,而不是你所展示的内容 - 因为你给出的代码肯定会起作用,对我来说也是如此。