异步方法是在调用时还是在等待时抛出异常? [英] Do async methods throw exceptions on call or on await?
问题描述
当我调用异步方法并取回任务时,它会立即抛出还是会等到我等待任务后?
When I call an async method and get a task back, will that immediately throw or will it wait until I await the task?
换句话说,这段代码行得通吗?还是我也必须将方法调用包装在try块中?
In other words, will this code work? Or will I have to wrap the method call in the try-block as well?
Task task = ThisMethodWillThrow();
try
{
await task;
}
catch (Exception e)
{
Console.WriteLine("oops");
}
推荐答案
两者都是可能的.如果该方法实际上是 async
(即在声明中使用C# async
关键字),则C#编译器将其包装为始终可靠地抛出 await
,但必须注意,这不是不是编写可以 await
-ed的方法的唯一方法,因此:如果您不控制被调用的方法( ThisMethodWillThrow
)并且不能依赖于实现的知识,那么 try
最好包含初始调用,以及 await
.
Both are possible. If the method is actually async
(i.e. uses the C# async
keyword in the declaration), then the C# compiler wraps it up in such a way that it will always reliably throw on the await
, but it is important to note that this is not the only way to write a method that can be await
-ed, so: if you don't control the method being called (ThisMethodWillThrow
) and can't rely on knowledge of the implementation, it would be better for the try
to include the initial invoke, as well as the await
.
作为将立即抛出而不是在 await
中抛出的方法的示例:
As an example of a method that will throw immediately rather than in the await
:
Task ThisMethodWillThrow() { // note that this is **not** "async", but is awaitable
if (thingsAreBad) throw new SomeException();
return SomeInnerMethod();
}
async Task SomeInnerMethod() { ... }
可能会想:好吧,只需使所有等待的方法 async
来避免这种情况"-像这样:
It might be tempting to think "well, just make all awaitable methods async
, to avoid this" - like:
async Task ThisMethodWillThrowToo() { // note that this is "async"
if (thingsAreBad) throw new SomeException();
await SomeInnerMethod();
}
但是:在某些情况下,异步机制在经常同步,有时是异步"的情况下是非常可衡量的性能开销,因此,对性能至关重要的等待代码(例如IO/网络代码)的常见优化是:除非我们知道我们实际上已经进入异步路径,否则积极避免使用 async
机制.
However: there are scenarios where the async machinery is a very measurable performance overhead in the "often sync, sometimes async" case - and so a common optimization in performance critical awaitable code (IO/network code, for example) is to actively avoid the async
machinery unless we know that we're actually falling into the asynchronous path.
这篇关于异步方法是在调用时还是在等待时抛出异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!