This is the third visitation of the topic of UI and worker thread interaction. Based upon excellent feedback through the comments (thanks Peter Ritchie and others) I have renamed and modified the previous ThreadBarrier implementation (which was a poor name to begin with since a thread barrier concept already represents something else). The previous pattern of encapsulating a thread and communicating to the UI via events raised on the UI thread is still my recommendation: see the first post for a long winded explanation, and the second post for more examples. However, there are many people that already have existing code that uses the Control.InvokeRequired and Control.Invoke pattern such as:

The new implementation is intended to replace this code and support the original ThreadBarrier concept.

Introducing the DelegateMarshaler

The DelegateMarshaler implementation is virtually identical to the ThreadBarrier except for four minor differences:

The marshaler is created using a static method DelegateMarshaler.Create() so an exception can be thrown if no SynchronizationContext exists (console app, or before UI is started, etc.)

If the calling thread is already the target thread (UI thread), then the delegate is invoked normally rather than a cross thread invoke. This is similar to InvokeRequired being false.

The DelegateMarshaler supports methods with 0 to 4 arguments.

Static methods wrap ThreadPool.QueueUserWorkItem in a type safe way.

A compact example

void buttonDownload_Click(object sender, EventArgs e)

{

DelegateMarshaler marshaler = DelegateMarshaler.Create();

DelegateMarshaler.QueueOnThreadPoolThread(

(fileName) =>

{

//simulate download

for (int i = 0; i < 100; ++i)

{

marshaler.Invoke(UpdateProgressBar, i);

Thread.Sleep(50);

}

marshaler.Invoke(ShowDownloadComplete, fileName);

},

“somefile.txt”);

}

privatevoid UpdateProgressBar(int progress)

{

this.progressBarDownload.Value = progress;

}

privatevoid ShowDownloadComplete(string fileName)

{

this.labelFileDownload.Text = fileName;

}

Using the DelegateMarshaler consists of creating the marshaler on the UI thread and invoking the methods that update the UI (preferably from the worker thread). Invoke will call the method synchronously, and BeginInvoke will call the method asynchronously allowing the worker to continue running while the UI updates. If your thread is a separate method altogether (which is usually the case), you would want to save the DelegateMarshaler instance as a private field in your form or control so it can be used in the thread method.

The DelegateMarshaler Implementation

publicsealedclassDelegateMarshaler

{

privateSynchronizationContext _synchronizationContext;

publicstaticDelegateMarshaler Create()

{

if (SynchronizationContext.Current == null)

{

thrownewInvalidOperationException(“No SynchronizationContext exists for the current thread.”);

Previously I introduced the ThreadBarrier pattern which describes a simple technique for allowing worker threads to easily and safely communicate with controls on the UI thread. The key points from the previous article are:

A worker thread is completely contained within a class (and any objects the class references)

Events from this worker class are raised on the UI thread

A SynchronizationContext is used rather than Control.Invoke or Dispatcher.Invoke

The UI code does not have to worry about what thread is executing, it always assumes the UI thread (keeps code clean)

The ThreadBarrier needs to be created on a UI thread to capture the UI’s SynchronizationContext

Today’s article is a revisitation of the pattern to demonstrate several ways the technique can be used, as well as describe the flaw in the previous implementation. Yesterday’s article on events and threads provides an in depth background on the subtleties of events and multithreading. The contents of today’s post include:

The use of an anonymous delegate can be used for either implementation. The .NET 3.5 version uses a lambda expression just to demonstrate an alternate way of invoking the action.

Sample UI and Worker Classes

The sample UI and worker classes are very simple examples that will be the reference code for the techniques that follow. The UI code remains virtually unchanged throughout every technique which is ideal since it should not be concerned with threading:

The two classes above are doing nothing special to communicate with on another. An attempt to use the two together would fail since the worker class is raising events on the worker thread which is not allowed to access controls on the UI thread. Amazingly using a ThreadBarrier in the following way causes all events from the worker class to be automatically raised on the UI thread:

publicclassThreadBarrierWeatherChecker : WeatherChecker

{

privateThreadBarrier _threadBarrier;

public ThreadBarrierWeatherChecker()

{

this._threadBarrier = newThreadBarrier();

}

protectedoverridevoid OnTemperatureChanged(WeatherEventArgs e)

{

this._threadBarrier.Post(base.OnTemperatureChanged, e);

}

protectedoverridevoid OnWindChanged(WeatherEventArgs e)

{

this._threadBarrier.Post(base.OnWindChanged, e);

}

protectedoverridevoid OnHumidityChanged(WeatherEventArgs e)

{

this._threadBarrier.Post(base.OnHumidityChanged, e);

}

protectedoverridevoid OnStopped(EventArgs e)

{

this._threadBarrier.Post(base.OnStopped, e);

}

}

That’s it! All it took was deriving from the worker class and posting the method that raises the events to the UI thread. The UI class should create an instance of ThreadBarrierWeatherChecker rather than WeatherChecker. This technique is handy if you do not own or can’t modify the code to the worker class.

ThreadBarrier Technique #2: Using extension methods on a SynchronizationContextThis technique requires the developer to not only have access to the WeatherChecker code, but also capture the UI’s SynchronizationContext in the WeatherChecker’s constructor:

Again if the developer is in full control of the worker class, all that it takes is deriving from a ThreadBarrier to inherit the method that provides the posting to the UI thread:

publicclassWeatherChecker : ThreadBarrier

Raising the events is now a matter of calling the Post method in the base ThreadBarrier class:

Post(OnTemperatureChanged, newWeatherEventArgs(Rand(30f)));

Post(OnWindChanged, newWeatherEventArgs(Rand(15f)));

Post(OnHumidityChanged, newWeatherEventArgs(Rand(100f)));

In order for the ThreadBarrier to work the WeatherChecker class needs to be created on the UI thread so the base ThreadBarrier class can capture the UI’s SynchronizationContext.

ThreadBarrier Technique #4: Creating an instance of a ThreadBarrier

If deriving from a ThreadBarrier is not an option, just creating an instance of a ThreadBarrier will work as well. This implementation is similar to the extension method sample, but the ThreadBarrier instance will hide the capturing and storing of the SynchronizationContext. This technique also requires the WeatherChecker to be created on the UI thread.

This technique should be a last resort for the scenario where you can’t derive from the worker class and you are unable to modify its code. Since an extra set of events need to be created and subscribed, it can be dangerous and lead to memory leaks if the handlers are not properly removed.

The adapter class needs to provide a way to attach and detach to an already existing WeatherChecker instance. If the instance is not detached, it will result in a memory leak (the adapter class will be kept alive).

The Original ThreadBarrier Implementation Flaw

The first implementation of the ThreadBarrier used the event as a parameter:

The problem with this implementation is that the event handler delegate is copied when passed to the method. During execution of this method (which occurs on the worker thread) a UI thread could remove the original handler and dispose of the UI control. Since the method’s copy of the delegate will still get posted to the UI thread, the handler will be executed in the control’s code even though the control was already disposed. In other words, if the worker class is being used by multiple windows or controls that are opening and closing it could lead to this problem. See Problem #2 in the Events and Threads post.

ThreadBarrier FAQ

Q: Why not just use AsynchOperationManager.SynchronizationContext in the base class for each method post?A: Since the methods are originally called on the worker thread, it means the call to the AsynchOperationManager.SynchronizationContext static property will be made from the worker thread. It will thus return an ‘empty’ SynchronizationContext. The call to the static property must be made on the UI and the SynchronizationContext must be ’saved’ so the worker can use it.

Q: Why not just use SynchronizationContext.Current?A: The static SynchronizationContext.Current returns null when called from a worker thread, while AsynchOperationManager.SynchronizationContext will at least return an empty SynchronizationContext so we at least have some context reference.

Q: What is the difference between a ThreadBarrier and BackgroundWorker?A: The BackgroundWorker must also be created on a UI thread. However, the BackgroundWorker does not provide an easy and transparent way (other than ReportProgress) to post events and data from the worker to the UI thread. A ThreadBarrier will support any kind of event since it uses generics.

Q: Why not use WPF’s built in cross-thread binding support?A: A ThreadBarrier can be used in combination with WPF’s cross-thread binding. The difference is that a ThreadBarrier (and events) allow arbitrary code in the UI to execute. Properties just represent data.

With the advent of multi-core processors becoming standard in desktop PCs, it is clear we are on the verge of a shift in which high level software is designed and developed. First there was Object Oriented programming, then design patterns, and now there is multithreading. Multithreading has been around for decades in high end computing, but due to the now wide availability of multiple cores in a standard PC or laptop, it is only now that it is beginning to gain mainstream attention. There is a lot of work to do for tools, frameworks, and patterns to simplify the design and debugging of multithreading programs. While Microsoft has been working diligently to improve their tools (Visual Studio) and frameworks (Task Parallel Library) to bring multithreading into the mainstream, there is not yet enough guidance and information on the internet about proper threading techniques and design patterns.

This is where the ‘ThreadBarrier’ pattern comes in. Ultimately it is a way to help simplify the interaction between the UI and worker threads. A ThreadBarrier is an encapsulation of thread execution inside a class such that it is not exposed to the outside world. Rather, external events are first posted to the UI thread so any listener (on the UI thread) does not have to worry about threading issues. Like any pattern, there are times where it is ideal to use and there are times where it does not apply. Use at your own discretion.

Background

It seems that nearly every introductory threading example on the internet consists of a button click that starts a thread that performs some operation in a worker thread in the UI code behind. While simple examples are good, this immediately introduces a developer to starting threads In UI code and thinking that such techniques are normal.

The Problem

The problem is that the only way most developers know how to get data back to the UI thread is to use a UI control to post back the information. In case you are new to threading: the golden rule is that all UI controls (windows, textboxes, progressbars, etc.) can only be accessed from the thread that created them (the UI thread of course). This means a worker thread cannot do myTextBox.Text=”asdf” otherwise a cross-thread exception will be thrown. Controls provide a mechanism for executing a method on the UI thread (Control.Invoke, Control.BeginInvoke, Dispatcher.Invoke, Dispatcher.BeginInvoke).

There are tricks to make this a bit cleaner, but that is the common way to update the UI from any thread.

The combination of the Control’s UI thread rule and a Control’s ability to invoke on the UI thread essentially handcuffs developers into mixing threads with the UI and trying to make it work. Perhaps some have tried to be smart and hide the threads away deep in non-UI code to keep the UI clean. Those developers probably end up with the following questions (at least I did):

“How the heck do you get a control for invoking that deep in the execution and far away from the UI code? And more importantly, why does it have to be this way? There has to be a better way.”

The Answer

There is a better way, and it involves a SynchronizationContext. Rather than use a Control to post execution back to the UI, a SynchronizationContext provides this same capability without the UI Control requirement. Since a fantastic CodeProject article already covers the SynchronizationContext in depth, a summary will only be described here.

SynchronizationContext Overview

-SynchronizationContext is an abstract base class for:
-WindowsFormsSynchronizationContext
-DispatcherSynchronizationContext
-WinForms automatically creates an instance of WindowsFomsSynchronizationContext for a WinForms UI thread.
-WPF automatically creates an instance of DispatcherSynchronizationContext for a WPF UI thread.
-Static property AsyncOperationManager.SynchronizationContext gets the SynchronizationContext for the calling thread: WindowsFormsSynchronizationContext in WinForms and DispatcherSynchronizationContext in WPF.
-SynchronizationContext provides two methods (Send and Post) for synchronous or asynchronous method invocation.
-Getting AsyncOperationManager.SynchronizationContext on a non-UI thread (such as in a console app or worker thread) returns the base SynchronizationContext class that just invokes a method on the calling thread when Send is used, and calls a method on a ThreadPool thread when Post is used.

Introducing the ThreadBarrier ‘Pattern’

The ThreadBarrier pattern consists of a non-UI class encapsulating and executing a worker thread and always raising its events on the UI thread using a SynchronizationContext. The worker thread execution should never leave the class via events. Data and objects within the class may be operated upon by the worker thread but all external events must be called on the UI thread. If this technique is correctly followed then the listening UI code does not need to worry about thread checks and delegate posting.

Implementing a ThreadBarrier’ (.NET 2.0)

A ThreadBarrier can be implemented as an abstract class so that derived classes automatically inherit the necessary functionality to support the pattern.

The SyncronizationContext must be stored as a field so that it can be used by the worker thread in the derived class. Since the static AsyncOperationManager.SynchronizationContext property is called in the constructor, a critical requirement of properly using a ThreadBarrier derived class is that it must be created on the thread in which events want to be raised. In other words, create the class on the UI thread so that the UI’s context is captured. A worker thread can then use this context to post the methods that raise events back to the UI. The following protected method can be used for posting OnXXX methods:

Now the WeatherChecker class does not have to derive from a ThreadBarrier (but it now has to do the work in its constructor of saving a reference to the SynchronizationContext, the task previously left for the abstract ThreadBarrier class).:

The ThreadBarrier technique is an easy way to simplify the use of a worker thread and how it interacts with the UI. It is not the silver bullet for multithreading, but it does offer a way to think of a thread as an ‘object’ and hide the threading complexities. The UI and worker thread can be separated even further by designing a ThreadBarrier class to do nothing but handle events from other threading code (such as in a library that you do not have the code) and propagate just these events to the UI. This truly allows the business ‘logic’ to be free of any UI dependencies.

Original Problem
Many times I have encountered a scenario where all I need to do is perform some small operation that takes a considerable amount of time. If I execute this operation on the UI thread, the UI will block until the operation is complete. Obviously this is not ideal. To address this need, the .NET engineers created the BackgroundWorker class in .NET 2.0. Its purpose is to execute a simple operation on a worker thread, and it does this very well. However, that is only half the battle. If an operation is happening in the background and the user needs to be notified of its progress, the BackgroundWorker must be wired up to some display that displays the progress. In WinForms, developers had many problems initially because they were trying to update controls from the worker thread. .NET 2.0 and later throws an exception if this cross-thread control updating is attempted since it is not allowed in either WinForms or WPF. If you did not know already, all UI controls can only be modified from the thread that created them (the UI thread). There are many examples scattered throughout the internet describing how a developer must ‘post’ the information back to the UI thread before updating a control, such as:

WPF to the rescueWPF has come to the rescue with its support for cross-thread property binding and notification. In other words, you can bind a progress bar’s current value to a property that gets changed on another thread. WPF will handle cross thread invoking automatically. This means it becomes very easy to design a WPF window that can not only display the progress of an operation, but also status text and other items that may be updated on the worker thread as an operation progresses, all without having to worry about invoking, callbacks, and threads.

Since most simple operations have the same pattern, a simple interface can be designed that simple operations can implement. We can then design a single WPF window that will display the progress of an operation by attaching to the interface rather than the simple operation:

Once the ProgressWindow and IProgressOperation classes are complete, many simple operations can be designed without having to worry about implementing another UI to display their progress. Here is an example of the IProgressOperation interface:

Now we can implement a simple class that exports event logs, and implements this interface. Start() will start the BackgroundWorker, CancelAsync() will set a flag that the operation will check periodically, and the properties Total and Current provide the progress information needed for a progress display.

Now for the WPF window that will display this IProgressOperation. Since we will make the window implement INotifyPropertyChanged, when the ProgressChanged or ProgressTotalChanged events are raised from the background operation (and coming from a worker thread), we will just raise the events for WPF to update its bindings:

Finally we have the XAML for the ProgressWindow that shows how it has both progress text and the Progressbar bound to the Current and Total properties that the window exposes to itself from the IProgressOperation.

The ProgressWindow will call the Start() method on the IProgressOperation once the window has completely loaded.

Keep in mind that this ProgressWindow is a very simple example demonstrating the power of WPF and binding. It can easily be extended to display many other items such as status text or other information, all using binding and not having to worry about invoking on the UI thread. You can also use the concepts provided in this article to design your own more powerful and customized ProgressWindow.