WPF and Multi-threaded programming design

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.

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 programmer

    In 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 { getset; }

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.

Posted in Uncategorized | Leave a comment

OCZ Revo Drive – Fixed!

OCZ Revo Drives are amazing – with two 64GB SSDs combined in a RAID 0 configuration and slipped into a PCIe motherboard slot there’s really nothing faster!

Only problem is, after a few weeks of using it, Windows would say there were problems with the hard drive and check it on boot – which takes a normally really fast boot up time and makes it, well, really slow. Other times it Windows wouldn’t check anything, but it would just hang – often for 2 minutes! – just showing this:

No fancy little balls of light for two minutes!! I tried digging into the Windows Event log but never found anything actionable.

Today, it got worse – MUCH worse! During a disk check it crashed (I’ve never seen that before), then it wouldn’t start, then it did start but it blue-screened several times… You get the idea.

Anyway, here’s how I (think I) eventually fixed it without a low-level format!

  1. I have an ASUS P5K-VM mother board and I was a version behind on the BIOS – so I upgraded to version 1001 which is documented as fixing the “Q-Fan function abnormal after recover from S3 mode.” However, I have noticed that often motherboard updates fix a lot more than they advertise for some reason.
  2. Then I downloaded the OCZ Revo upgrade disk and burned it to a CD. The upgrade process was wonderfully simple and immediately upgraded my OCZ Revo firmware from 1.2 to 1.35.

I’ve restarted multiple times, put the computer to sleep and woken it up then restarted, etc. I’ve turned the computer off and then on again and it has always started lightning fast! Wonderful.

Thank you OCZ engineers!!

Robert

Posted in Uncategorized | Leave a comment

Problem installing Dragon Naturally Speaking v11.5

I ordered a Dragon Naturally Speaking 11.5 CD, but much to my dismay, it wouldn’t install. I got the following error –

(Error opening installation log file. Verify that the specified log file location exists and is writable)

So I used process monitor to look at what it was doing, and right around the error it was trying to write to find a temporary directory to write to.

This temporary directory existed, so I wasn’t sure exactly what the problem was; so I looked at my %temp% environment variable just to be complete and sure enough:

Opps! I had a second directory on my temp environment variable for some reason. Removing this secondary directory fixed the problem!

If you’re encountering this, the way to remove this with Windows 7 is to right click on your computer icon and choose “Properties”:

Then, on the left side choose “Advanced system settings”:

Then click on “Environment Variables”:

Then, (finally) click on TEMP in the upper list and click “Edit”. Delete the duplicate path (everything from the end to and including the first semi-colon) and you should be good to go.

I am installing Dragon Naturally Speaking v11.5 as we speak (so I had to type in this blog post).

Robert

Posted in Uncategorized | Leave a comment