Search code examples
c#wpfmultithreadingdispatcher

Change WPF controls from a non-main thread using Dispatcher.Invoke


I have recently started programming in WPF and bumped into the following problem. I don't understand how to use the Dispatcher.Invoke() method. I have experience in threading and I have made a few simple Windows Forms programs where I just used the

Control.CheckForIllegalCrossThreadCalls = false;

Yes I know that is pretty lame but these were simple monitoring applications.

The fact is now I am making a WPF application which retrieves data in the background, I start off a new thread to make the call to retrieve the data (from a webserver), now I want to display it on my WPF form. The thing is, I cannot set any control from this thread. Not even a label or anything. How can this be resolved?

Answer comments:
@Jalfp:
So I use this Dispatcher method in the 'new tread' when I get the data? Or should I make a background worker retrieve the data, put it into a field and start a new thread that waits till this field is filled and call the dispatcher to show the retrieved data into the controls?


Solution

  • The first thing is to understand that, the Dispatcher is not designed to run long blocking operation (such as retrieving data from a WebServer...). You can use the Dispatcher when you want to run an operation that will be executed on the UI thread (such as updating the value of a progress bar).

    What you can do is to retrieve your data in a background worker and use the ReportProgress method to propagate changes in the UI thread.

    If you really need to use the Dispatcher directly, it's pretty simple:

    Application.Current.Dispatcher.BeginInvoke(
      DispatcherPriority.Background,
      new Action(() => this.progressBar.Value = 50));