【发布时间】:2013-08-21 07:38:29
【问题描述】:
当等待一个出错的任务(一个设置了异常的任务)时,await 将重新抛出存储的异常。如果存储的异常是AggregateException,它将重新抛出第一个并丢弃其余的。
如何在使用await的同时抛出原来的AggregateException,才不会不小心丢失错误信息?
请注意,当然可以为此考虑一些 hacky 解决方案(例如,在 await 周围尝试捕捉,然后调用 Task.Wait)。我真的很想找到一个干净的解决方案。 这里的最佳做法是什么?
我曾想过使用自定义等待器,但内置的 TaskAwaiter 包含很多我不知道如何完全重现的魔法。它调用 TPL 类型的内部 API。我也不想想要重现所有这些。
如果你想玩,这里有一个简短的再现:
static void Main()
{
Run().Wait();
}
static async Task Run()
{
Task[] tasks = new[] { CreateTask("ex1"), CreateTask("ex2") };
await Task.WhenAll(tasks);
}
static Task CreateTask(string message)
{
return Task.Factory.StartNew(() => { throw new Exception(message); });
}
Run 中仅抛出两个异常之一。
请注意,Stack Overflow 上的其他问题并未解决此特定问题。建议重复时请小心。
【问题讨论】:
-
您是否看到这篇博客文章解释了他们为什么选择像他们一样为
await实施异常处理? blogs.msdn.com/b/pfxteam/archive/2011/09/28/10217876.aspx -
好的,谢谢。对于一般情况,我有点同意这种推理,但我的用例没有被涵盖。
-
“在所有情况下,Task 的 Exception 属性仍然返回包含所有异常的 AggregateException,因此您可以捕获抛出的任何异常,并在需要时返回查看 Task.Exception。”
-
这是一个保留所有异常并正确传播取消状态的解决方案:stackoverflow.com/a/62607500/1768303
标签: c# task-parallel-library c#-5.0 async-await