MVVM: Using a Timer in your ViewModel

Binding / Coding / MVVM / Silverlight / WPF

Yesterday I found myself needing to periodically sample data for a real-time chart and realized that the “Timer” classes in System.Threading and System.Windows didn’t quite work as expected, raising the following exception:

The calling thread must be STA, because many UI components require this.

We get this error because when we use the other Timer classes they create a separate thread in the background on which the “Tick”/”Elapsed” events are raised; this is an issue when updating “notify-able” properties which are bound to elements in the UI because the UI must be edited from the thread it was created on (not thread-safe).  This proves itself to be rather inconvenient when using a pattern like MVVM, where we don’t have a handle to an element from the UI in our ViewModel to synchronize with. After a bit of googling and playing around, I discovered the DispatcherTimer class in System.Windows.Threading.  As it works out, this timer’s “Tick” event is always raised on the main UI thread.

Here’s a brief example of one way to implement the DispatcherTimer:

// This code creates a new DispatcherTimer with an interval of 15 seconds.
DispatcherTimer timer = new DispatcherTimer();
...
timer = new DispatcherTimer();
timer .Interval = new TimeSpan(0, 0, 15);
timer .Tick += new EventHandler(this.InvalidateSampleData);

// Start the timer.  Note that this call can be made from any thread.
timer.Start();
...
private void InvalidateSampleData(object state, EventArgs e)
{
    // Timer callback code here...
}

Over and out!

Cyle


Programming enthusiast. I've been intrigued by computers since I was 12, staying in at recess to code QBASIC on the old Apple II. Background in the payment industry, particularly in card switching and related system architecture. Lover of high-performance distributed architecture. Huge fan of the new NoSQL wave. Open source fanatic.

Leave a Reply