WPF ate my Control.Invoke

Today I ran into the dreaded cross-thread UI call in my WPF application. In WinForms I’m quite familiar with the solution: check Control.InvokeRequired. If it returns True, then you’re making a cross-thread call and must Invoke the method on the UI thread. Some quick air code:

Sub Foo(ByVal bar As String)
  If (Me.InvokeRequired) Then
    Me.Invoke(New Action(Of String)(AddressOf Foo), bar)
  Else
    TextBox1.Text = bar
  End If
End Sub

In WPF, there is no Control.InvokeRequired. Instead, there’s Dispatcher.CheckAccess, which returns False if you’re making a cross-thread call. Good luck finding the CheckAccess method if you don’t know about it: it’s hidden from IntelliSense.

Most of the samples I found online (and I found plenty of blog posts) reference the control’s Dispatcher object, e.g. TextBox1.Dispatcher.CheckAccess. Unfortunately, my cross-thread call was occurring in my ViewModel, in a method that updated a property with a binding in the View. Like any good ViewModel, mine is completely ignorant of the View and all of its controls.

Fortunately, there’s a dispatcher on the Application object itself: Application.Current.Dispatcher. From there, I could use Dispatcher.CheckAccess and Dispatcher.Invoke to resolve the problem.

Hopefully this post saves someone else a few minutes of searching.

Advertisements

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s