当我调用异步方法并取回任务时,它会立即抛出还是会等到我等待任务后?
换句话说,这段代码行得通吗?还是我也必须将方法调用包装在try块中?
Task task = ThisMethodWillThrow();
try
{
await task;
}
catch (Exception e)
{
Console.WriteLine("oops");
}
答案 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();
}
机制,除非我们知道我们实际上正在陷入异步路径。