liveBook · Manning

ConfigureAwait

As explained in C# Concurrency: Asynchronous and multithreaded programming

ConfigureAwait(false) configures an await continuation not to capture the current SynchronizationContext or TaskScheduler.

ConfigureAwait(false) tells await not to capture the current SynchronizationContext or TaskScheduler for its continuation. It does not mean “always switch threads”: completed tasks continue immediately on the current thread, and asynchronous work is not made background work merely by marking a method async. section 11.3 section 11.6

Use the continuation rules to choose deliberately:

  • Preserve the default await behavior when subsequent code needs a UI thread, thread settings, or thread-local storage. section 11.7
  • Use ConfigureAwait(false) when continuation code does not depend on the current context and should use the default task scheduler, normally the thread pool. section 11.6 section 11.7
  • Do not assume a thread change: an already completed Task bypasses the continuation scheduling decision. section 11.3 section 11.6

Keep UI code on the UI thread

A WinForms event handler should normally await the operation and then update the control. Applying ConfigureAwait(false) to the handler continuation can move execution away from the UI thread, making `label1.Text = result` invalid. Keeping ConfigureAwait(false) inside the non-UI method allows that method to avoid the context while the handler resumes on the UI context. If every continuation deliberately avoids the context, marshal the update explicitly with `BeginInvoke`.

Listing 11.13 Deadlock prevented by using ConfigureAwait(false)
private void button1_Click(object sender, EventArgs ea)
{
   var task = DoSomething();
   label1.Text = task.Result;
}
 
private async Task<string> DoSomething()
{
   await Task.Delay(500).ConfigureAwait(false);            #1
   return "done";
}

Inspect the complete deadlock example and the single ConfigureAwait(false) change that prevents the continuation from requiring the blocked UI context. section 11.3

How C# Concurrency: Asynchronous and multithreaded programming covers it

How deep it goes
Explains context and scheduler selection, completed-task behavior, deadlocks, and UI safeguards without detailing compiler-generated state machines.
Examples
Uses console thread IDs, completed tasks, WinForms handlers, UI marshaling, and blocking Result deadlocks.
What it assumes
Assumes familiarity with C# tasks and await while clarifying context capture, scheduling, completed tasks, and UI-thread constraints.
What you can do after
Diagnose/debug continuation placement, prevent context-related deadlocks, and preserve UI correctness with appropriate await usage.
How it connects
Connects async/await with SynchronizationContext, TaskScheduler, thread pools, UI threading, and deadlocks.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of C# Concurrency: Asynchronous and multithreaded programming. The section links point to the parts of the book it draws on.