Based on numerous books and blogs including this excellent one here, it is clear that when one writes a dll library exposing helper async methods i.e. the wrapper methods, i
When the task is awaited, it creates a corresponding TaskAwaiter
to keep track of the task which also captures the current SynchronizationContext
. After the task completes, the awaiter runs the code after the await ( called the continuation) on that captured context.
You can prevent that by calling ConfigureAwait(false)
, which creates a different kind of awiatable (ConfiguredTaskAwaitable
) and its corresponding awaiter (ConfiguredTaskAwaitable.ConfiguredTaskAwaiter
) that does not run the continuation on the captured context.
The point is that for each await
, a different instance of an awaiter is created, it is not something that is shared between all the awaitables in the method or program. So it's best that you call ConfigureAwait(false)
for each await
statement.
You can see the source code for the awaiters here.