Background
Today a friend of mine wrote me,
We are finally writing our first production WPF application which is fun. Where do you put your async stuff? Is it in your ViewModels? If so, how do you test them?
I’m currently writing a very complex piece of software for scientific researchers – it allows the non-programming savvy scientific researcher the ability to write their own programs in a highly specialized domain-language that I have created specifically for this purpose. There is a lot of threading going on…
Common threading uses
- I use multi-threading when the application is starting to initialize suitable sub-components simultaneously (and report progress to the user)

- Similarly, during long-running data exports from the database I use threading to report progress to the user via a progress-bar and respond quickly to cancel requests.

The language itself
- I also use threading to decouple the very slow data persistence layer from the very performance hungry requirements of the domain-language execution. A running program written in the domain language saves a lot of data, and I don’t want to slow-down the running program waiting for the hard drive to persist it all. So the database layer has its own threads for persisting data.
-
Even the domain-language itself allows multi-threading, although it is hopefully completely transparent. For example, here is a small snippet of the domain-language written by a scientific researcher (note that I didn’t write this for this post) that is inherently multi-threaded:
define phase FixationPhase
// Take away the food hopper – they need to earn the food
move FoodHopper to down position// Show the fixation circle on the screen
fixation.colour = #55AA2B
fixation.IsVisible = true// If the subject clicks the fixation circle then
// we need to move to the next phase
when fixation.ClickCount changes then
goto phase Test1Phase
end when
wait(60min * 24)
end phase
This is multi-threaded in a few ways:
- First, the WPF GUI and the “codes” (as programs written in this domain-language have come to be called) run on their own threads. This of course helps keeps the IDE responsive and also allows the experimenter to use the IDE and review data while the subject is running through the experiment on a second monitor.
- But even within the experiment this is multi-threaded. The second last line contains a wait(60min * 24) which obviously needs to wait for 24 hours. But if the subject clicks on the fixation shape, then the when clause needs to run, which in this case means going to a completely different phase of the experiment and cancelling the wait request. As shown in the sample above the domain-language makes this easy (hopefully!), but under the covers there is a fair bit of non-trivial threading and cross-thread communication happening to make all of this work and work very fast.
- First, the WPF GUI and the “codes” (as programs written in this domain-language have come to be called) run on their own threads. This of course helps keeps the IDE responsive and also allows the experimenter to use the IDE and review data while the subject is running through the experiment on a second monitor.
Logging
-
I also use the wonderful Gibraltar Hub so that I can analyse application performance; specifically I’m looking for memory leaks and degrading performance over time, but of course if there are errors in the log I want to see those as well. By default Gibraltar sends the log files when the application exits, but I’ve discovered that scientific-researches tend to leave the program running all the time, and they never shut off the computers. This means that the logs can become very large and are very rarely sent. I asked the wonderful folks at Gibraltar (they really are amazing) if there was a better way and there was:
Gibraltar 3.0 will make incremental updates of logs much more efficient, but you can address the long running session issue now. You should call Log.SendSessions or Log.SendSessionsAsync once in a while — maybe on a timer.
Easy enough. My original solution was much more complex than it needed be, using threads and wait handles. But when I re-read their comment just now I realized that the much more elegant approach is to use a timer – just like they suggested.
There are actually three Timer classes in .NET:
System.Timers.Timer - Seems easier to use, but less documentation on which thread will make the call
System.Threading.Timer - More powerful but a little more complex
System.Widnows.Forms.Timer - Obviously not really useful for the WPF programmerIn this case I don’t need the extra power, so I’m using the System.Timers.Timer timer.
In my static constructor:
const int oneHourInMs = 1000*60*60; _sendActiveLogTimer = new System.Timers.Timer(oneHourInMs); _sendActiveLogTimer.Elapsed += � (sender, e) => Gibraltar.Agent.Log.SendSessionsAsync(SessionCriteria.ActiveSession);And then in the class itself declared at the bottom of the file along with all my other data:
/// <summary>
/// A timer used to periodically send the active logs
/// to the Gibraltar hub.
/// </summary>
private static readonly System.Timers.Timer _sendActiveLogTimer;
The view-model and threading
For all of these examples, NONE of them are in the view-model! Typically if you’re talking about threading in the context of WPF you’re talking about using the Dispatcher to “move” a background thread request to the GUI thread. There’s a very complete MSDN article Build More Responsive Apps With The Dispatcher that discusses how this is typically done (it also discusses a new timer class for WPF, the DispatcherTimer).
In fact, I work hard to avoid dealing with the Dispatcher in my view-model, because if I was to switch to the web, WinForms, or Windows8 stuff the dispatcher logic could be completely different, reducing the overall use of the view-model. My goal with the view-model is to imagine a different delivery mechanism for the application that nevertheless looks and works very similar (perhaps so that users can switch back and forth between the two types of applications more easily). So perhaps a Windows 8 version for tablets; of course I’d like to use the same view-model layer if at all possible. Maybe that’s just dreaming and I’m making a (very small) amount of work for myself but I think it’s still worthwhile to strive for the goal: the worst that has happened to me as a result of this is a very clean view-model layer. ![]()
Domain logic layer collections
One place where I do deal with the dispatcher in the view-model layer is when I’m wrapping observable collections. With .NET 4 the ObservableCollection(Of T) class has been nicely placed in the System.Collections namespace (specifically System.Collections.ObjectModel) and the always present System.dll making it very acceptable to use in the domain logic layer. This is a great help and simplification from .NET 3 and 3.5 where we had to jump through hoops to have the view-model layer notified when a collection changed.
However, the WPF GUI really doesn’t like receiving CollectionChanged events from a background thread, and it usually complains bitterly by throwing an InvalidOperationException exception.
However, to simplify – or rather completely eliminate – the need to deal with the dispatcher on a regular basis I use aspect oriented programming. Specifically, I use the amazing and very well designed PostSharp from SharpCrafters. They actually document two very nice dispatcher aspects that can cause a method to automatically run on the GUI thread or a background worker thread.
So after searching my entire code-base for this attribute I found only two occurrences – one when the domain-logic-layer adds a shape to the screen, and the other when it is removed:
/// <summary> /// Called when a new shape is added to the domain-logic layer "screen". /// </summary> [ExecuteOnGuiThread] private void OnShapeAddedToDomainLogicLayerScreen( object sender, ShapeEventArgs e ) { Check.Requires(sender!=null, "The event sender should not be null"); Check.Requires(sender!=null, "The shape event arguments should not be null"); // etc… }
Every other occurrence of the ExeucteOnGuiThread aspect in my solution is in the presentation layer where I have the presentation layer subscribing to an event from something that is documented as possibly raising the event on a background thread (such as the splash-screen progress callback or the data-export progress call-back).
Testing
So how do I test this stuff? Unfortunately, usually I test it manually, which is why I try and keep it to a minimum! Another option is to modify your dispatcher code – as I have done – so that you can control the dispatcher that is used, or tell it not to use a dispatcher at all. This means that in your unit tests you can configure no dispatcher and your unit test is essentially single-threaded. This is useful for GUI tests, but not necessary when testing methods attributed with the execute-on-background-thread aspect. This is because although it’s tricky, it’s not really that hard to test multi-threaded code in the domain logic and database layers. For this reason (and improved reuse of course) this is why I much prefer multi-threaded code to be in a non-GUI related layer.
My customized ExecuteOnGuiThread aspect
Extending the PostSharp aspect is remarkably simple – you just have to get over the increasingly common yet unjustified paranoia of all things static. Most unit test zealots will tell you that using static member variables – especially public ones – make your code less testable. However in this case we’re actually using a public static property to make our code much easier to test.
So, in my ExecuteOnGuiThreadAttribute aspect I declare the following public static property:
/// <summary>
/// The dispatcher for application’s user interface thread.
/// </summary>
public static Dispatcher ApplicationUiDispatcher { get; set; }
In my unit tests I simply don’t bother to set this and then the aspect will run it on the same thread as the rest of the unit test, simplifying the unit test greatly.
However, in my actually application start-up code I simply set this as follows:
ExecuteOnGuiThreadAttribute.ApplicationUiDispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher;
And then any code with that aspect applied will use the application dispatcher.
Here’s the actual code for the aspect’s OnInvoke() method to make this happen pretty seamlessly:
/// <summary>
/// Called when the method this aspect has been applied to is called.
/// </summary>
public override void OnInvoke(MethodInterceptionArgs eventArgs) {
// By default, use the application’s UI-thread dispatcher
// which should be setup when the application starts
Dispatcher dispatcher = ApplicationUiDispatcher;
// Is the target method on a DispatcherObject instance?
// If so, use it’s dispatcher instead.
var dispatcherObject = eventArgs.Instance as DispatcherObject;
if( dispatcherObject!=null )
dispatcher = dispatcherObject.Dispatcher;
if( dispatcher==null )
dispatcher = Dispatcher.CurrentDispatcher;
Contract.Assert(dispatcher!=null);
// Are we okay to call this method from the current thread?
if( dispatcher.CheckAccess() )
eventArgs.Proceed();
else {
// Invoke the method on the correct thread asynchronously
Action method = eventArgs.Proceed;
dispatcher.BeginInvoke(this.Priority, method);
}//else
}
From then on, most of the time you really don’t have to think about it at all – things just work the way they should. That means that I can be a more productive programmer because I’m thinking about the domain problem and not complex threading issues. Once again, a carefully designed aspect makes us much more productive.
It also means that my view-model layer has no threading code in it whatsoever.
The Presentation layer and threading
For the data-export progress I cheated a little and by-passed the view-model layer. In my data-export component I defined a generic interface:
/// <summary>
/// Common functionality between data exporters.
/// </summary>
public interface IDataExporter {
/// <summary>
/// Raises events to indicate the progress of exporting the data.
/// </summary>
event EventHandler<ExportProgressEventArgs> ExportProgress;
/// <summary>
/// Allows the export process to be cancelled.
/// </summary>
void Cancel();
…
}
My dialog box WPF window actually has two constructors – which is something that a lot of WPF developers seem to forget is possible. The first is your basic default constructor created by Visual Studio when I created the Window, and is used by Visual Studio and Expression Blend:
public ExportProgressWindow() {
InitializeComponent();
}
The second constructor is the one my command uses (in this case, the command is defined in the GUI – which I don’t mind because this particular common would need to be re-written for a dramatically different GUI version of the application anyway). This second constructor expects to be given an instance of an ISessionExporter interface, and the first thing it does is subscribe to the OnExportProgress event.
public ExportProgressWindow( ISessionExporter exporter ) {
Check.Requires(exporter!=null, “The exporter must not be null”);
// Still need to initialize the component
InitializeComponent();
// Save the data for later use
_exporter = exporter;
_exporter.ExportProgress += this.OnExportProgress;
}
The OnExportProgress method of course has my ExecuteOnGuiThread aspect applied to it, making it then easy to update the progress bar control on the dialog box:
/// <summary>
/// Called when the data exporter exports another record
/// </summary>
[ExecuteOnGuiThread]
private void OnExportProgress(object sender, ExportProgressEventArgs e) {
…
}
So in this case I’m not using MVVM for my progress bar, but instead I cheated slightly and was done programming the feature slightly faster. In this case I believe the choice was the right one, because the data-export code is still highly abstracted by the interface, and the dialog box is not likely to change so much in the future that I would wish I had a view-model layer. Additionally, in this case there is very little data-translation that needs to be done, which also reduced the usefulness of trying to build a view-model to encapsulate the data-export progress.
I hope this helps,
Robert
PS. I appologise the crazy colours and font changes – it looked great in Word and then I published it to the blog and it went crazy.