when should I use ConfigureAwait(true)

true to attempt to marshal the continuation back to the original context captured; otherwise, false.

It's actually more like saying that ConfigureAwait(true) is like using .ContinueWith( t => {...}, TaskScheduler.FromCurrentSynchronizationContext()), where ConfigureAwait(false) is like using .ContinueWith( t => {...}). If you pass false, then the continuation is being allowed to run on a thread-pool thread instead of pulling back to the current synchronization context.


One possibility I can see is if you're writing code in a library and you want to allow your callers to decide whether it's appropriate to continue on the original context1 (although I'd usually argue for never continuing on the original context from within library code)

Your caller will either pass a bool parameter or set some configuration value, and so you will not know until runtime what the correct argument value is.


This is the general type of answer for APIs such as this that have a no-args variant and a variant with a single argument, where the no-args variant is documented as "the same as the single argument variant with well-known value x" - if you won't know until runtime what the correct value to pass is, then you should just call the single argument variant with the correct runtime value.


1 E.g. your caller is also supplying a delegate. Your caller will know (and can decide) whether that delegate needs to be back on the original context or not.


Since true is the default option I cannot see when would you ever use it.

One obvious use case is when you want to make sure that every time something is awaited, there is made an explicit and deliberate choise about what to do with the synchronization context.

Example policy from http://newmedialabs.co.za/blog/post/SynchronizationContexts:

At NML we prefer to always state explicitly how we want the task continuation to occur. So even though a Task's default is ConfigureAwait(true), we still specify it as such so that we are always cognizant of what's happening "under the hood".

Although to improve readability they use an extension instead of ConfigureAwait(true) directly:

However, when you look at a lot of code, some with ConfigureAwait(true) and some with ConfigureAwait(false), it's not easy to spot where they differ. So we use either ConfigureAwait(false), or a useful extension method, ContinueOnCapturedContext(). It does the same thing, but just differentiates it from ConfigureAwait(false) in a more visual manner.