【问题标题】:Where to catch exception in async code?在哪里捕获异步代码中的异常?
【发布时间】:2015-07-20 01:59:26
【问题描述】:
Task task = AsyncMethod();

// do other stuff

await task;

AsyncMethod() 可以抛出异常。我是在方法调用、await 周围放置 try-catch,还是两者都放置?

【问题讨论】:

标签: c# exception async-await try-catch


【解决方案1】:

为了避免关于异常处理应该发生在哪里的整个争论,我将稍微改变您的问题:在哪里可以捕获从AsyncMethod 方法抛出的异常。

答案是:你在哪里await它。

假设您的 AsyncMethod 方法如下所示:

private async Task AsyncMethod()
{
    // some code...
    throw new VerySpecificException();
}

...那么您可以通过这种方式捕获异常:

Task task = AsyncMethod();

// do other stuff

try
{
    await task;
}
catch(VerySpecificException e) // nice, I can use the correct exception type here.
{
    // do something with exception here.
}

只需对其进行测试,您就会看到await 关键字是如何完成从返回的Task 中解包和抛出异常的所有工作的,这种方式使编写try-catch 块感觉非常自然。

相关文档:try-catch.

注意异步方法中的异常部分所说的:

要捕获异常,请在 try 块中等待任务,并在关联的 catch 块中捕获异常。

【讨论】:

  • @Micky:是的,但是在这种情况下,OP 显然会返回一个Task,这是正常情况。
  • 谢谢。无论如何,您对我问题的重新表述更像是我要问的;)
  • 在阅读了链接的文档后,我对它的理解更好了——实际上是 await 导致了异常,因为任务处于故障状态。现在有道理了,谢谢@sstan
  • @Brett:是的,完全正确。 await 关键字解包并抛出异常,因此它的行为非常透明,甚至可以很好地抛出正确的原始异常类型,而不是更烦人的 AggregateException。
  • @Dear downvoter:我总是愿意学习。如果我说错了,不要害怕发表评论。我不会咬人的:)
猜你喜欢
  • 1970-01-01
  • 2011-03-07
  • 1970-01-01
  • 2015-04-26
  • 2018-04-03
  • 2011-05-12
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
相关资源
最近更新 更多