Tips and Tricks with the Dispatcher and DispatcherPriority in WPF

It wasn’t until I’d used WPF for about a year that I really started to appreciate the value of using the Dispatcher to execute chunks of code asynchronously with a specific DispatcherPriority. Now I would say I use this a couple of times a day and find it invaluable.

In this series of posts, I’m going to introduce the Dispatcher object and DispatcherPriority enum, and outline some of the useful ways to leverage them.

In this first post I’ll introduce the Dispatcher and DispatcherPriority, and then I’ll follow it up with posts showing some uses for them:

    1. Execute a Method Asynchronously Using the Dispatcher Queue
    2. Load the Data for a Window Asynchronously After It Has Rendered
    3. Load the Items in a ListBox Asynchronously
    4. Implement Application.DoEvents in WPF
    5. BackgroundCommand (and demo)
    6. Silverlight – combo box
    7. Dual Targeting – DispatcherHelper

 

Introducing the Dispatcher and DispatcherPriority

 

If you need to execute a method asynchronously without blocking the UI thread, you can invoke the method on the Dispatcher property of a UI element, and specify a System.Windows.Threading.DispatcherPriority that’s lower than the Render priority.

In WPF, most objects ultimately derive from System.Windows.Threading.DispatcherObject, and only the thread that created a DispatcherObject may access that object. For example, a background thread cannot update the contents of a TextBox that was created on the UI thread.

The DispatcherObject exposes a System.Windows.Threading.Dispatcher  property called Dispatcher. This has a method called BeginInvoke which takes a System.Delegate as one of its parameters. When BeginInvoke is called, the Dispatcher will schedule this delegate for execution in its event queue. When it’s due execution, the Dispatcher will execute this delegate on the same thread on which its owner was created. The BeginInvoke method is asynchronous and returns to the caller immediately.

The second parameter expected by BeginInvoke is a DispatcherPriority, which controls when the delegate is due execution. It does this by informing the Dispatcher of the priority of this event, relative to the other pending operations in the event queue. Events will be executed only when there are no higher priority events in the queue. This is useful for specifying that a certain process should be executed, for example, in the background or when the application is idle, but should not block more important events such as those concerned with loading or rendering the element.

For example, Microsoft Word uses this mechanism for spell checking. Spell checking is done in the background using the idle time of the UI thread.

The table below shows the values of the DispatcherPriority enum in ascending order of priority, lowest to highest:

Name Value
Invalid –1
Inactive 0
SystemIdle 1
ApplicationIdle 2
ContextIdle 3
Background 4
Input 5
Loaded 6
Render 7
DataBind 8
Normal 9
Send 10

Because the Dispatcher executes the delegate in the same thread that was used to create the component, the code in the delegate can update and interact with the control. This is the simplest way possible of executing a method asynchronously, without exposing yourself to complex synchronization issues such as race conditions, deadlocks, live locks, and memory corruption.

Next I’ll post a simple example of how to use the Dispatcher and DispatcherPriority, and then move on to some more useful applications.

Tags: ,

Leave a comment