异步方法是在调用还是在等待时抛出异常?

The*_*off 5 c# async-await

当我调用异步方法并恢复任务时,是否会立即抛出或等待我等待任务?

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

Task task = ThisMethodWillThrow();

try
{
    await task;
}
catch (Exception e)
{
    Console.WriteLine("oops");
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 9

两者都有可能.如果该方法实际上是async(即async在声明中使用C#关键字),那么C#编译器会以一种总是可靠地抛出它的方式将其包装起来await,但重要的是要注意这不是唯一的方法.编写一个可以成为await-ed 的方法,所以:如果你不控制被调用的方法(ThisMethodWillThrow)并且不能依赖于实现的知识,那么最好try包括初始调用,以及await.

作为一个立即抛出而不是在await:

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

可能会被容易让人联想到"好,只是让所有awaitable方法async,避免这种" -这样的:

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

但是:有场景中的异步机器是在一个非常可测量的性能开销"经常同步,有时异步"的情况下-并因此在性能关键awaitable代码共同优化(IO /网络代码,例如)是积极地避免async机器,除非我们知道我们实际上已落入异步路径.