Dispatcher where have you been all my life?

I’ve been working a project for my company dealing with WPF, and while a lot is touted about the cool graphics, the amazing 3D visuals, as a developer on of the simplest, yet most rockin’ features of this presentation framework is it’s threading model. When I first heard that WPF was (essentially) single threaded I was most disappointed. That was until I learned what was meant by "essentially". WPF uses a Dispatcher class which acts as a wrapper for a Thread, the power of this class comes with two pieces of functionality. A DispatcherPriority enumeration and PushFrame(). DispatcherPriority allows you to specify whether the work to be done on the UI thread is more urgent than displaying the UI itself (which it rarely is if your doing stuff on the UI thread).  The benefit of this becomes more apparent when you learn that if you use WPF’s DependencyObject as a base class for your data objects, that all your data objects must be created the UI thread. Hang on.. that’s a detriment not a benefit… now when I de-serialize from disk have to do it on the UI thread. This is the stumbling block I hit when coding our application. I was faced with two options either invoke the de-serialize on the UI thread or not use DependencyObject. Well DependencyObject makes data-binding work properly (for the first time in the history of any UI framework I might add) so I wasn’t about to do that. The alternative… Dispatcher.BeginInvoke(DispatcherPriority.Background). 

If you’ve worked with Windows Forms you’d realise that using BeginInvoke on the UI only partially solves your problem the whole block of code you invoke still locks the UI thread and then so does the corresponding UI update that inevitably happens next. The only benefit of BeginInvoke in WinForms is you aren’t waiting around for the UI to start running the code. But with the magic of WPF, the Dispatcher dispenses with this issue because the Data-binding code that occurs for it is automatically scheduled after you’ve changed the fields on the object. This means you get a super-responsive UI as your objects are created and added to a ListView for example as my code (which loads a single object) exits without waiting for a UI update, data-binding takes care of it at some later point.

All this led me to create a new type of threading component called the ForegroundWorker, based on similar principles to the BackgroundWorker where you call RunMultipleAsync(IEnumerable<T>) and the worker splits up the work to be performed on each object separately, By calling the DoWork function on the foreground thread.  This lead to massive performance improvements in my UI and I highly recommend doing this if you have to work with Serialized DependencyObjects.

I could go on and on about how Dispatcher "just seems" faster and better than Thread.Start or ThreadPool.QueueUserWorkItem, and how I got major performance improvements using DispatcherTimer over Timer. But that’s enough rant from me for one day.

Advertisements
  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: