I've read about ConfigureAwait in various places (including SO questions), and here are my conclusions:
ConfigureAwait(true): Runs the rest of the code on the same thread the code before the await was run on.ConfigureAwait(false): Runs the rest of the code on the same thread the awaited code was run on.- If the await is followed by a code that accesses the UI, the task should be appended with
.ConfigureAwait(true). Otherwise, an InvalidOperationException will occur due to another thread accessing UI elements.
My questions are:
- Are my conclusions correct?
- When does
ConfigureAwait(false)improve performance, and when does it not? - If I am writing for a GUI application but the next lines don't access the UI elements, should I use
ConfigureAwait(false)orConfigureAwait(true)?
To answer your questions more directly:
Not necessarily the same thread, but the same synchronization context. The synchronization context can decide how to run the code. In a UI application, it will be the same thread. In ASP.NET, it may not be the same thread, but you will have the
HttpContextavailable, just like you did before.This is not correct.
ConfigureAwait(false)tells it that it does not need the context, so the code can be run anywhere. It could be any thread that runs it.It is not correct that it "should be appended with
.ConfigureAwait(true)".ConfigureAwait(true)is the default. So if that's what you want, you don't need to specify it.Returning to the synchronization context might take time, because it may have to wait for something else to finish running. In reality, this rarely happens, or that waiting time is so minuscule that you'd never notice it.
You could use
ConfigureAwait(false), but I suggest you don't, for a few reasons:ConfigureAwait(false), the continuation can run on any thread, so you could have problems if you're accessing non-thread-safe objects. It is not common to have these problems, but it can happen.ConfigureAwait(false)is easy to spot (it could be in a different method than where the exception is thrown) and you/they know what it does.I find it's easier to not use
ConfigureAwait(false)at all (except in libraries). In the words of Stephen Toub (a Microsoft employee) in the ConfigureAwait FAQ:Edit: I've written an article of my own on this topic: .NET: Don’t use ConfigureAwait(false)