Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ConfigureAwait: On which thread is the exception handled?

When you await a Task, the continuation by default runs on the same thread. The only time you ever actually need this is if you're on the UI thread, and the continuation needs to run on the UI thread as well.

You can control this by using ConfigureAwait, e.g.:

await SomeMethodAsync().ConfigureAwait(false);

...which can be useful to offload work from the UI thread that doesn't need to run there. (But see Stephen Cleary's comment below.)

Now consider this bit of code:

try
{
    await ThrowingMethodAsync().ConfigureAwait(false);
}
catch (Exception e)
{
    // Which thread am I on now?
}

And how about this?

try
{
    await NonThrowingMethodAsync().ConfigureAwait(false);

    // At this point we *may* be on a different thread

    await ThrowingMethodAsync().ConfigureAwait(false);
}
catch (Exception e)
{
    // Which thread am I on now?
}
like image 472
Petter Hesselberg Avatar asked Feb 01 '16 17:02

Petter Hesselberg


People also ask

What does ConfigureAwait () do?

ConfigureAwait(continueOnCapturedContext: false) is used to avoid forcing the callback to be invoked on the original context or scheduler. This has a few benefits: Improving performance.

What is the default value of ConfigureAwait?

In 99% of the cases, you should use ConfigureAwait(false). In . NET Framework by default the Task execution will continue on the captured context, this is ConfigureAwait(true).

What is ConfigureAwait do in async await?

By default, when you use async/await, it will resume on the original thread that started the request. However, if another long-running process currently has taken over that thread, you will be stuck waiting for it to complete. To avoid this issue, you can use a method called ConfigureAwait with a false parameter.

Where is ConfigureAwait false used?

As a general rule, every piece of code that is not in a view model and/or that does not need to go back on the main thread should use ConfigureAwait false. This is simple, easy and can improve the performance of an application by freeing the UI thread for a little longer.


1 Answers

The exception will be on whatever thread the continuation would have happened on had there been no exception.

try
{
    await ThrowingMethodAsync().ConfigureAwait(false);
}
catch (Exception e)
{
    // Which thread am I on now?
    //A: Likely a Thread pool thread unless ThrowingMethodAsync threw 
    //   synchronously (without a await happening first) then it would be on the same
    //   thread that the function was called on.
}

try
{
    await NonThrowingMethodAsync().ConfigureAwait(false);

    // At this point we *may* be on a different thread

    await ThrowingMethodAsync().ConfigureAwait(false);
}
catch (Exception e)
{
    // Which thread am I on now?
    //A: Likely a Thread pool thread unless ThrowingMethodAsync threw 
    //   synchronously (without a await happening first) then it would be on the same
    //   thread that the function was called on.
}

For some more clarity:

private async Task ThrowingMethodAsync()
{
    throw new Exception(); //This would cause the exception to be thrown and observed on 
                           // the calling thread even if ConfigureAwait(false) was used.
                           // on the calling method.
}

private async Task ThrowingMethodAsync2()
{
    await Task.Delay(1000);
    throw new Exception(); //This would cause the exception to be thrown on the SynchronizationContext
                           // thread (UI) but observed on the thread determined by ConfigureAwait
                           // being true or false in the calling method.
}

private async Task ThrowingMethodAsync3()
{
    await Task.Delay(1000).ConfigureAwait(false);
    throw new Exception(); //This would cause the exception to be thrown on the threadpool
                           // thread but observed on the thread determined by ConfigureAwait
                           // being true or false in the calling method.
}
like image 188
Scott Chamberlain Avatar answered Nov 06 '22 06:11

Scott Chamberlain