ConfigureAwait: On which thread is the exception handled?

自古美人都是妖i 提交于 2020-01-01 09:55:16

问题


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?
}

回答1:


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.
}


来源:https://stackoverflow.com/questions/35136801/configureawait-on-which-thread-is-the-exception-handled

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