Multi-threaded WPF Application: Dispatcher Invoke. A more efficient way?

Sparky picture Sparky · Mar 28, 2011 · Viewed 42.8k times · Source

I am using .NET 3.5 .

I am making a WPF application for a project and I was just looking a bit of insight regarding the Dispatcher and multithreading. An example of my program:

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(
                        () =>_aCollection.Add(new Model(aList[i], aSize[i]))));

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(
                        () => _Data.Add(new DataPoint<double, double>(Id, aList[i]))));

 Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(
                        () => _historical[0].Add(aList[i])));

I understand that WPF does not like when another thread accessing an object other than the one that created it. However, I was thinking there has to surely be a better way than making so many dispatcher invokes, could someone please push me in the right direction at least (if there is a better solution that is).

Answer

A.R. picture A.R. · Mar 28, 2011

You can start by being less verbose in your calls, i.e.

Application.Current.Dispatcher.Invoke(() =>_aCollection.Add(new Model(aList[i], aSize[i])));

Another trick that I like to use is to make a shortcut method like this:

public static void UiInvoke(Action a)
{
  Application.Current.Dispatcher.Invoke(a);
}

Then you have even less to do, as in:

UiInvoke(() =>_aCollection.Add(new Model(aList[i], aSize[i])));

Using dispatcher.Invoke() is really just how you get the action back onto the UI thread, which is probably where these objects (_aCollection) were created in the first place. If the items in question don't have direct interaction with the UI thread, then you can create / manipulate them on a different thread, removing the need to use the dispatcher. Of course this approach could become more complicated depending on what you are doing.