This is a shorter post with a small solution to a problem, but I wanted to add it here for my own reference. I have recently been working on a little WPF pet project as I want to learn XAML and WPF. I seemed to miss that generation of UI technology when I went from mainly doing WinForms work into WCF and back end enterprise development.

The issue I had the other day was that I had a timer running in my code that triggers an event when the elapsed time hits a certain time. From that event handler I wanted to update something on the user interface. If I update that UI item directly from the event I got the following exception being thrown. This is because the UI is operating on a different thread to the thread handling the timer event.

Thread Exception
Thread Exception

The solution is to use the Dispatcher.Invoke( Action ) method to make the call to the UI thread. This is demonstrated in the following example. We have a timer being setup with an event (OnTimedEvent) being fired every 5 seconds. When the OnTimedEvent is called, the UI is updated inside the Dispatcher.Invoke( Action ) method.

private Timer _timer = new Timer();
_timer = new Timer(5000);      
_timer.Elapsed += OnTimedEvent;
timer.Enabled = false;

private void OnTimedEvent( Object source, ElapsedEventArgs e)
     Dispatcher.Invoke(() =>
          // Set property or change UI compomponents.              

MSDN describes this solution as follows:

In WPF, only the thread that created a DispatcherObject may access that object. For example, a background thread that is spun off from the main UI thread cannot update the contents of a Button that was created on the UI thread. In order for the background thread to access the Content property of the Button, the background thread must delegate the work to the Dispatcher associated with the UI thread. This is accomplished by using either Invoke or BeginInvoke. Invoke is synchronous and BeginInvoke is asynchronous. The operation is added to the event queue of the Dispatcher at the specified DispatcherPriority.

Invoke is a synchronous operation; therefore, control will not return to the calling object until after the callback returns.

Leave a Reply

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

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

Google photo

You are commenting using your Google 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 )

Connecting to %s

%d bloggers like this: