多线程WPF应用程序:Dispatcher Invoke。一种更有效的方式?

时间:2011-03-28 19:30:23

标签: c# wpf multithreading dispatcher

使用.NET 3.5

嗨,大家好,我正在为一个项目制作一个WPF应用程序,我只是看了一下Dispatcher和多线程的一些见解。我的计划的一个例子:

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])));

据我所知,当另一个线程访问除创建它之外的对象时,WPF不喜欢。但是,我认为必须有一个更好的方法,而不是让这么多的调度员调用,至少有人请你把我推向正确的方向(如果有更好的解决方案)。

干杯, Sparky的

4 个答案:

答案 0 :(得分:15)

你可以从你的电话中减少冗长开始,即

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

我喜欢使用的另一个技巧是创建一个这样的快捷方法:

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

然后你甚至可以做更少的事情,如:

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

使用dispatcher.Invoke()实际上就是如何将操作返回到UI线程,这可能是首先创建这些对象(_aCollection)的地方。如果有问题的项目没有与UI线程直接交互,那么您可以在不同的线程上创建/操作它们,从而无需使用调度程序。当然,这种方法可能会变得更加复杂,具体取决于您正在做什么。

答案 1 :(得分:13)

最简单的方法是将所有三个调用合并为一个:

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(
                        () =>
                      {
                          _aCollection.Add(new Model(aList[i], aSize[i]);
                          _Data.Add(new DataPoint<double, double>(Id, aList[i]);
                          _historical[0].Add(aList[i])
                      }));

答案 2 :(得分:6)

如果您使用.Net 4.0,我会考虑使用System.Threading.Tasks。这似乎是continuations的一个主要示例。

答案 3 :(得分:2)

您的问题源于事实,ObservableCollection不会自动将更改分派给UI线程。这与简单的INotifyPropertyChanged不同,它自动完成。我建议创建自己的特定ObservableCollection,它实现INotifyCollectionChanged,自动调度对UI线程的更改。

您可以在此处查看示例:SynchronizedObservableCollection and BindableCollection

旧答案/问题: 您使用DependencyObjectDependencyProperties进行绑定吗?如果是,则放弃它。它被多次讨论过,这是使用INotifyPropertyChanged代替的更大原因之一。只需要使用调度程序就是修改GUI对象本身的属性而且从你的例子中可以明显看出,这不是你在做什么。绑定本身通过调度程序自动运行。

另见View Models: POCOs versus DependencyObjects