Ok, with the bad pun out of the way I wanted to talk about some of the features for multithreading present in the new operating system from Microsoft: Windows Vista™. In one of my earlier posts I mentioned how a software developer should review the available platform and user interface toolkit to examine the ways in which it may help to tackle multithreading. In this post I will present some things I’ve discovered in .NET 3.0 Windows Presentation Foundation (WPF).
Along with the reputed advances to the OS kernel with regards to multithreading, there are advances to the windowing API that ships with Vista. Microsoft seems to realize the need for a deep down way to insulate the developer as much as possible from the intricacies of multithreaded programming. And this is good for me and you. Microsoft has traditionally done very well with developer enablement in general. It just makes good business sense; the better that apps run on their OS the more value that OS has in general. While the aforementioned insulation (discussed below) can go a long way for multithreaded productivity there are cases in which spawning new threads and/or managing your own threading can still be beneficial. Of course you’re not tied to using any one mechanism. You’re free to choose the way that best suits you.
All authors of windowing toolkits have sometimes struggled over how to thread their APIs. In WPF the designers stuck with a single threaded approach. This decision probably has as much to do with interoperability with existing code (COM, IE, Copy & Paste, etc.) than anything else. While still having objects with single thread affinity (STA) the designers of WPF wanted to deliver an improved mechanism for thread exclusivity and communication. Enter the Dispatcher.
The dispatcher is a prioritized work queue that is created on the UI thread of any WPF application. This mechanism functions much like a message loop or “pump” does in traditional Win32 apps. With some additional magic related to the DependencyObject class (parent of nearly every WPF class), virtually every item in WPF can reference its owning thread’s dispatcher object. All work necessary to the running of your app (mouse moves, repaints, etc.) passes through this queue. You can use this facility to queue and prioritize any task you choose. Immediately your application can be more responsive with out of the box classes. The key is to realize that you control the importance of your task vs. the UI repainting, etc. Another trick is to fine tune what should go into this queue and what deserves its own dedicated thread. See the relevant sections of the Windows SDK for more information.
The WPF framework also utilizes the Dispatcher class to ensure mutual exclusivity between threads. For instance, just like you’ll get an exception in .NET 1.x and 2.0 when trying to update a UI control from, say, a background thread, you’ll receive the same exception in WPF. Cross thread communication is achieved in the same way as before but is much improved as well. Instead of marshaling a call with Invoke() to an individual control you schedule the operation with the dispatcher for the thread via the synchronous Invoke() or its asynchronous cousin BeginInvoke(). This is of course with the added prioritization ability.
With the new Dispatcher feature your apps can take advantage of a new way to prioritize tasks and provide better responsiveness. Of course you can also retain older ways of breaking down background tasks but another tool in the toolbox is never bad. The Dispatcher is simply a newer way to enable threaded operations as well as ease inter-thread communication.
Jason Shigley