navigation
 Thursday, May 15, 2008

In a Windows Presentation Foundation (WPF) application, you are only allowed to update UI objects in the thread that created them, which for UI objects will be the main UI thread.

If you have code that needs to check whether it is in the correct thread or not before updating the UI, you can use the CheckAccess method of DispatcherObject, which is the base class of all UI elements (via Visual, and DependencyObject). CheckAccess will return false if you may not update the object that you called CheckAccess on from the current thread (there is a related method, VerifyAccess, which raises an Exception if you are not in the right thread).

For instance, in the following code, if I find I need to switch to the UI thread, I call BindTree() on the main thread by using Dispatcher.Invoke and an anonymous delegate, otherwise I call it on the current thread (_tv is a TreeView).

public void Load(XElement tocRoot)
{
  if (!_tv.CheckAccess())
    Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal,
      (ThreadStart)delegate { BindTree(); });
  else
    BindTree();
}

Another pattern you can use is to call your own method in the main thread if need be:

public void SetPercent(int percent)
{
    if (Thread.CurrentThread != Dispatcher.Thread)
        Dispatcher.Invoke(DispatcherPriority.Normal,
            (ThreadStart)delegate { SetPercent(percent); });
    else
    {
        double p = percent / 100.0;
        txtPercent.Text = p.ToString("P0");
        rctComplete.Width = p * rctProgress.Width;
    }
}

In the example above, if I am not in the right thread, I call the method I am in, but now in the correct thread.

Note that here I use a different way to check the thread and call the dispatcher. In this example, the method SetPercent is in a UserControl, so I have access to the Dispatcher member variable. In the previous example, the Load method being called was in a regular C# class that did not inherit from anything visual, so I had to use Application.Current.Dispatcher.

I hope this helps you with your threading woes!

 |