Do async methods throw exceptions on call or on await?

江枫思渺然 提交于 2020-08-07 05:13:57

问题


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?

Task task = ThisMethodWillThrow();

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

回答1:


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.

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() { ... }

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();
}

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.



来源:https://stackoverflow.com/questions/53445650/do-async-methods-throw-exceptions-on-call-or-on-await

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!