liveBook · Manning

SynchronizationContext

As explained in C# Concurrency: Asynchronous and multithreaded programming

SynchronizationContext is a .NET abstraction for posting or sending callbacks to a particular execution context, such as a UI thread.

SynchronizationContext is a .NET abstraction for scheduling callbacks onto a particular execution context, such as a UI thread. Background work can use it to report results without directly touching UI objects from the wrong thread. section 4.3 section 11.2

A context is associated with a thread through SynchronizationContext.SetSynchronizationContext. Code running on that thread can then capture the current context, allowing await to schedule continuation code appropriately. section 11.2 section 5.2

Use the context according to the callback behavior required:

  • Post queues a callback and returns without waiting; await uses Post for continuations. section 11.2
  • Send runs a callback on the target context and waits for it to finish. section 11.2
  • WinForms and WPF provide framework-specific alternatives through Control.BeginInvoke or Dispatcher.BeginInvoke, while SynchronizationContext avoids direct UI-framework dependencies. section 4.3 section 11.2

A custom context can maintain a callback queue and have one thread consume it. Posting adds work to the queue; the consuming loop executes each callback on its own thread. This models how a single-threaded environment can preserve execution affinity. section 11.2

Preserving a single execution thread

A SingleThreadSyncContext can install itself, run an asynchronous startup delegate, and process queued continuations until the operation completes. With the context installed, code after await Task.Delay can run on the same managed thread rather than an arbitrary thread-pool thread. section 11.2

   public static void Run(Func<Task> startup)
   {
      var prev = SynchronizationContext.Current;
      try
      {
         var ctxt = new SingleThreadSyncContext();
         SynchronizationContext.SetSynchronizationContext(ctxt); #1
         ctxt.Loop(startup);                                     #2
      }
      finally
      {
         SynchronizationContext.SetSynchronizationContext(prev); #3
      }
   }

Shows installing a custom context, running the event loop, and restoring the previous context. section 11.2

   private BlockingCollection<(SendOrPostCallback call,object? state)> 
      _queue = new();
 
   private void Loop(Func<Task> startup)
   {
      startup().ContinueWith(t => _queue.CompleteAdding());      #1
      foreach(var next in _queue.GetConsumingEnumerable())       #2
      {                                                          #2
         next.call(next.state);                                  #2
      }                                                          #2
   }

Shows the blocking collection and consuming loop that execute posted callbacks on the context thread. section 11.2

Blocking the UI thread while waiting for work that must return through Send, Post, or await can deadlock: the callback cannot run until the blocked thread becomes available, leaving the UI frozen. section 4.3 section 5.5

How C# Concurrency: Asynchronous and multithreaded programming covers it

How deep it goes
Explains context association, Post versus Send, await behavior, and a queued single-thread implementation, but omits broader framework internals.
Examples
Demonstrates WinForms and WPF dispatch, a custom queued context, and await continuations before and after context installation.
What it assumes
Assumes familiarity with threads and asynchronous operations while explaining callback dispatch and context capture.
What you can do after
Build a custom single-thread context, preserve UI affinity, and diagnose deadlocks caused by blocking callbacks or await continuations.
How it connects
Connects asynchronous programming, await, callbacks, UI threads, thread pools, and TaskFactory.

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.