首页 > 解决方案 > 异步方法在调用或等待时会抛出异常吗?

问题描述

当我调用异步方法并取回任务时,它会立即抛出还是会等到我等待任务?

换句话说,这段代码会起作用吗?或者我是否也必须将方法调用包装在 try-block 中?

Task task = ThisMethodWillThrow();

try
{
    await task;
}
catch (Exception e)
{
    Console.WriteLine("oops");
}

标签: c#async-await

解决方案


两者都是可能的。如果该方法实际上是async(即在声明中使用了 C#关键字),那么 C# 编译器以这样一种方式包装它,async使其始终可靠地抛出 .编写一个可以-ed 的方法,因此:如果您不控制被调用的方法 ( ) 并且不能依赖于实现的知识,那么最好包含初始调用以及.awaitawaitThisMethodWillThrowtryawait

作为将立即抛出而不是在 中的方法的示例await

Task ThisMethodWillThrow() { // note that this is **not** "async", but is awaitable
    if (thingsAreBad) throw new SomeException();
    return SomeInnerMethod();
}
async Task SomeInnerMethod() { ... }

可能很容易想到“好吧,只需制作所有等待的方法async,以避免这种情况” - 比如:

async Task ThisMethodWillThrowToo() { // note that this is "async"
    if (thingsAreBad) throw new SomeException();
    await SomeInnerMethod();
}

但是:在某些情况下,异步机制在“经常同步,有时是异步”的情况下是一个非常可衡量的性能开销 - 因此性能关键的等待代码(例如 IO/网络代码)的常见优化是主动避免async除非我们知道我们实际上陷入了异步路径。


推荐阅读