Dispatch It

In WPF, like most UI frameworks, UI elements can only be updated from the thread they were created on. If you do background work, and want to affect the UI from a different thread, you’ll have to dispatch it. The Dispatcher class has a CheckAccess() method (which is marked as EditorBrowsableState.Never, making it invisible to intellisense for some reason.)

Here’s how you would normally use it:

delegate void CallMeDelegate(Button b);

void CallMe(Button b)
{
    if (!Dispatcher.CheckAccess())
    {
        Dispatcher.Invoke(DispatcherPriority.Normal, new CallMeDelegate(CallMe), b);
        return;
    }

    b.Foreground = Brushes.Red;
} 

You have to create a delegate, check for access and dispach if necessary. However, there's a smarter way, if you allow for a bit of Reflection:

void CallMe(Button b)
{
    if (UIHelper.EnsureAccess(MethodBase.GetCurrentMethod(), this, b))
    {
        b.Foreground = Brushes.Red;
    }
} 

What MethodBase.GetCurrentMethod() does is actually give you a method descriptor of the calling method (quite useful for a few scenarios! Too bad they don't have a GetCallerMethod() as well…) The EnsureAccess() method then checks with the dispatcher if we're on the right thread, and if not, dynamically dispatches it.

Last note: Dispatchers run a prioritized queue, so it can be handy to set the DispatcherPriority to something other than Normal. For example, if you set a Dependency Property's value, and want to do something after the UI was updated, try dispatching it with ContextIdle priority.

For more information about Dispatchers, you should read Nick Kramer's whitepaper.

Update: I also discovered the existence of the DispatcherSynchronizationContext, which inherits from the good old SynchronizationContext of .NET 2.0. The original one uses ThreadPool to queue items, while the WPF one uses the Dispatcher mechanism, which is more suitable for WPF. Note that this way you cannot specify a priority. I still believe the way I described above is slightly better.

Another Update: I've changed a few things in the implementation. Now it checks whether the object it receives is a DispatcherObject, and if so, uses its Dispatcher instead of the Application's. This is good for (the rare) cases where your UI itself runs in more than one thread.

Attachment: UIHelper.rar