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

时间:2018-11-23 11:14:18

标签: c# async-await

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

换句话说,这段代码行得通吗?还是我也必须将方法调用包装在try块中?

Task task = ThisMethodWillThrow();

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

1 个答案:

答案 0 :(得分:9)

两者都是可能的。如果该方法实际上是async(即在声明中使用C#async关键字),则C#编译器将其包装起来,使其始终可靠地抛出await ,但请务必注意,这不是不是编写可以await编辑的方法的唯一方法,因此:如果您不控制被调用的方法({ {1}},并且不能依赖于实现的知识,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() { ... } ,避免出现这种情况”-像这样:

async

但是:在某些情况下,异步机制在“经常同步,有时是异步”情况下具有非常可衡量的性能开销,因此,对性能至关重要的等待代码(例如IO /网络代码)的常见优化是: 积极避免使用async Task ThisMethodWillThrowToo() { // note that this is "async" if (thingsAreBad) throw new SomeException(); await SomeInnerMethod(); } 机制,除非我们知道我们实际上正在陷入异步路径。