Phase 22 of 30 · Topic 22.2

SynchronizationContext & `ConfigureAwait(false)` in Libraries

1Concept

By default, `await` captures the current `SynchronizationContext` (UI thread or ASP.NET Framework context) and marshals the continuation back to that thread. `ConfigureAwait(false)` bypasses context capturing, resuming on any available ThreadPool thread.

2Architecture Diagram

await httpClient.GetAsync(...); (Default)
├── Captures UI SynchronizationContext
└── Marshals continuation back to UI Thread (Thread Hop Overhead!)

await httpClient.GetAsync(...).ConfigureAwait(false);
├── Ignores SynchronizationContext
└── Resumes immediately on ThreadPool thread (High Speed!)

3Code Example

C# 13 & .NET 9
using System;
using System.Threading.Tasks;

public class ConfigureAwaitDemo
{
    public static async Task<int> LibraryComputeAsync()
    {
        // ConfigureAwait(false) in libraries prevents deadlocks and skips context hops
        await Task.Delay(10).ConfigureAwait(false);
        return 42;
    }

    public static async Task Main()
    {
        int result = await LibraryComputeAsync();
        Console.WriteLine($"Library Result: {result}");
    }
}

4Expected Output

Library Result: 42

5Key Takeaways

  • Always use `ConfigureAwait(false)` in class libraries and non-UI backend code.
  • Modern ASP.NET Core has NO `SynchronizationContext` by design.
  • Do not use `ConfigureAwait(false)` in UI event handlers that must touch UI controls directly.