In version 2.0 of the .NET Framework, Microsoft introduced the System.Threading. SynchronizationContext class. Simply stated, a SynchronizationContext-derived object connects an application model to its threading model. The FCL defines several classes derived from SynchronizationContext, but usually you will not deal directly with these classes; in fact, many of them are not publicly exposed or documented. Here is what the SynchronizationContext class looks like (I show only the members relevant to this discussion):

public class SynchronizationContext {
// Gets the SynchronizationContext-derived object
// associated with the calling thread
public static SynchronizationContext Current { get; }

// Invokes d asynchronously
public virtual void Post(SendOrPostCallback d, object state);

// Invokes d synchronously
public virtual void Send(SendOrPostCallback d, object state);

// SendOrPostCallback is a delegate defined like this:
public delegate void SendOrPostCallback(Object state);

Console and NT service applications have no threading model and therefore calling SynchronizationContext.Current will return null. For GUI applications such as Windows Forms, Windows Presentation Foundation, and Silverlight, the threading model dictates that all UI components must be updated by the thread that created them. So, when a GUI thread calls SynchronizationContext.Current, a reference to an object that knows how to invoke the d delegate on the calling GUI thread is returned. For ASP.NET applications, calling SynchronizationContext.Current returns a reference to an object that knows how to associates the original client request’s identity and culture with the calling thread before invoke the d delegate (which will be invoked on the same thread that calls SynchronizationContext’s Post or Send methods. In fact, for an ASP.NET SynchronizationContext object, the Post and Send methods do the exact same thing: they call the d delegate synchronously.

When working with the .NET Framework’s Asynchronous Programming Model (APM), understanding the SynchronizationContext is extremely important as it allows the callback method to be invoked using your application’s thread model. To simplify this, I wrote the following little method:

private static AsyncCallback SyncContextCallback(AsyncCallback callback) {
// Capture the calling thread’s SynchronizationContext-derived object
SynchronizationContext sc = SynchronizationContext.Current;

// If there is no SC, just return what was passed in
if (sc == null) return callback;

// Return a delegate that, when invoked, posts to the captured SC a method that
// calls the original AsyncCallback passing it the IAsyncResult argument
return asyncResult => sc.Post(
result => callback((IAsyncResult)result), asyncResult);

This method turns a normal AsyncCallback method into an AsyncCallback method that is invoked via the SynchronizationContext-derived object associated with the calling thread.