A few of my posts recently have dealt with surprises that I’ve found when interacting with different implementations of SynchronizationContext. This post is a summary of my findings.
|Specific Associated Thread||Synchronized Execution||Sequential Execution||Reentrant Send||Reentrant Post||Supports Equality Comparision|
|Windows Forms||Yes||Yes||Yes||Sometimes ||Never||Yes|
|Windows Presentation Foundation and Silverlight||Yes||Yes||Yes||Sometimes ||Never||No |
|Nito||Yes||Yes||Yes||Never ||Never||No |
|ASP.NET||No||Yes||No||Always||Always ||N/A |
- Send is reentrant when invoked from the same GUI thread; it is not reentrant when invoked from other threads.
- Invoking Send from the thread associated with a Nito.Async.ActionDispatcherSynchronizationContext is not allowed.
- As of .NET 3.5 SP1, WPF will create a separate DispatcherSynchronizationContext for each window, even if both windows are on the same thread.
- It is possible to create two different Nito.Async.ActionDispatcherSynchronizationContext instances that refer to the same underlying Nito.Async.ActionDispatcher.
- The “Supports Equality Comparision” property is meaningless because this SynchronizationContext type does not have a Specific Associated Thread.
- The rationale behind this surprising reentrancy is that the AspNetSynchronizationContext is not associated with any threads at all, so it borrows the thread from its caller.
The “Windows Forms” entry refers to the System.Windows.Forms.WindowsFormsSynchronizationContext, which is used by the GUI thread(s) in Windows Forms applications. Other threads in the same application may use different SynchronizationContext implementations.
The “Windows Presentation Foundation and Silverlight” entry refers to the System.Windows.Threading.DispatcherSynchronizationContext, which is used by the GUI thread(s) in Windows Presentation Foundation and Silverlight applications. Other threads in the same application may use different SynchronizationContext implementations.
The “Nito” entry refers to the Nito.Async.ActionDispatcherSynchronizationContext from the Nito.Async library. This includes Nito.Async.ActionThread threads.
The “Default” entry refers the default implementation of System.Threading.SynchronizationContext. This includes ThreadPool and Thread class threads, Windows Services, and Console applications, unless that thread replaces the default with a different SynchronizationContext.
The “ASP.NET” entry refers to the System.Web.dll:System.Web.AspNetSynchronizationContext, which is used by threads running in an application hosted by the ASP.NET runtime.
The “Specific Associated Thread” property means that the SynchronizationContext refers to a single, specific thread, and that queueing work to the SynchronizationContext will queue work to that thread. Note that multiple SynchronizationContexts may still refer to the same thread, even if this property is true.
The “Synchronized Execution” property means that all work queued to the SynchronizationContext will execute one at a time.
The “Sequential Execution” property means that all work queued to the SynchronizationContext will execute in order. If a SynchronizationContext supports Sequential Execution, then it also supports Synchronized Execution.
The “Reentrant Send” property means that the implementation of SynchronizationContext.Send will directly invoke its delegate on the current thread.
The “Reentrant Post” property means that the implementation of SynchronizationContext.Post will directly invoke its delegate on the current thread.
The “Supports Equality Comparision” property means that instances of that SynchronizationContext type may be compared for equality, and that equality implies that they refer to the same Specific Associated Thread.
Further Reading and a Useful Library
For more details, see the previous SynchronizationContext-related posts Gotchas from SynchronizationContext! and Another SynchronizationContext Gotcha: InvokeRequired?
The Nito.Async library contains a Nito.Async.SynchronizationContextRegister that can be used by a program to query properties of a SynchronizationContext implementation (except the “Supports Equality Comparision” property). This is useful when writing .NET multi-host-compatible asynchronous components.