简体   繁体   中英

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?

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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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