简体   繁体   English

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

[英]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? 当我调用异步方法并返回任务时,是否会立即抛出或等待我等待任务?

In other words, will this code work? 换句话说,这段代码会起作用吗? Or will I have to wrap the method call in the try-block as well? 或者我还必须在try-block中包装方法调用吗?

Task task = ThisMethodWillThrow();

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

Both are possible. 两者都有可能。 If the method is actually async (ie 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 . 如果该方法实际上是async (即在声明中使用C# async关键字),那么C#编译器会以一种总是可靠地抛出await的方式将其包装起来,但重要的是要注意这不是编写一个可以await的方法的唯一方法,所以:如果你不控制被调用的方法( ThisMethodWillThrow )并且不能依赖于实现的知识,那么try包含初始值会更好调用,以及await

As an example of a method that will throw immediately rather than in the await : 作为一个立即抛出而不是await的方法示例:

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

It might be tempting to think "well, just make all awaitable methods async , to avoid this" - like: 可能很容易想到“好吧,只是让所有等待的方法async ,避免这种情况” - 如:

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

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. 但是:在某些情况下,异步机制在“经常同步,有时是异步”的情况下是一个非常可测量的性能开销 - 因此,性能关键等待代码(例如IO /网络代码)中的常见优化是主动避免除非我们知道我们实际上属于异步路径,否则async机制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM