I often see recommended for async library code, that we should use ConfigureAwait(false)
on all async calls to avoid situations where the return of our call will be
I often see recommended for async library code, that we should use ConfigureAwait(false) on all async calls to avoid situations where the return of our call will be scheduled on a UI thread or a web request synchronization context causing issues with deadlocks among other things.
I recommend ConfigureAwait(false)
because it (correctly) notes that the calling context is not required. It also gives you a small performance benefit. While ConfigureAwait(false)
can prevent deadlocks, that is not its intended purpose.
It seems to me that a viable alternative is to simply set the current synchronization context to null at the top-level public-facing entry points of the library, and just forget about ConfigureAwait(false).
Yes, that is an option. It won't completely avoid deadlocks, though, because await will attempt to resume on TaskScheduler.Current if there's no current SynchronizationContext.
Also, it feels wrong to have a library replacing a framework-level component.
But you can do this if you want. Just don't forget to set it back to its original value at the end.
Oh, one other pitfall: there are APIs out there that will assume the current SyncCtx is what's provided for that framework. Some ASP.NET helper APIs are like that. So, if you call back end-user code, then that could be a problem. But in that case, you should explicitly document what context their callbacks are invoked in anyway.
However, I don't see many instances of people taking or recommending this approach.
It is slowly becoming more popular. Enough so that I've added an API for this in my AsyncEx library:
using (SynchronizationContextSwitcher.NoContext())
{
...
}
I haven't used this technique myself, though.
Are there any potential problems with this approach (other than the possible insignificant performance hit of having the await post to the default synchronization context)?
Actually, it's an insignificant performance gain.