It's widely recommended to use ConfigureAwait(false)
like this:
await Do1Async().ConfigureAwait(false);
// ...
await Do2Async().ConfigureAwait(false);
// ...
await Do3Async().ConfigureAwait(false);
// ...
IIRC, at the same time it's widely discouraged to use something like this ContextSwitcher
, which would switch the async execution flow context to a pool thread and thus might help avoiding that ConfigureAwait
infestation across my method:
await ContextSwitcher.SwitchToThreadPool(); // this was even removed from async CTP
await Do1Async();
// ...
await Do2Async();
// ...
await Do3Async();
// ...
Why is the 1st option considered a good practice and this one isn't, especially given the fact the code after await Do1Async().ConfigureAwait(false)
will continue on exactly the same conditions as the code after await ContextSwitcher.SwitchToThreadPool()
?
Also, there is another alternative:
await Task.Run(async () => {
await Do1Async();
// ...
await Do2Async();
// ...
await Do3Async();
// ...
});
IIRC, this is still better than the ContextSwitcher
option, but why?
Finally, there is still this interesting approach: An alternative to ConfigureAwait(false) everywhere.
Here is the relevant part of SynchronizationContextRemover
from the author's repo:
public void OnCompleted(Action continuation)
{
var prevContext = SynchronizationContext.Current;
try
{
SynchronizationContext.SetSynchronizationContext(null);
continuation();
}
finally
{
SynchronizationContext.SetSynchronizationContext(prevContext);
}
}
Is it safe to just remove the synchronization context like that, which AFAIU would affect the whole synchronous scope after await new SynchronizationContextRemover()
?
await new SynchronizationContextRemover();
// we are still on the same thread
// but the synchronization context has been removed,
// be careful...
// ...
await Do1Async();
// ...until now
How is this SynchronizationContextRemover
better than ContextSwitcher
, besides perhaps it has one less switch to a pool thread?