3

我一直在处理多线程问题。在过去的几天里,我一直在努力确保我所有的调用都是线程安全的。我刚刚遇到了一个困扰我的问题。这是场景:

我正在尝试使用 Infragistics XamDataChart 控件绘制波形,该控件通过 ~500 点/秒/波形。在启动应用程序时,我创建具有称为 WaveData 的 ObservableCollection 属性的对象,这些属性直接绑定到 itemscontrol 中的 xaml。当数据进入时,它被存储在一个队列中,并使用一个派生的工作线程来使数据出队并在适当的位置更新集合。

生成工作线程:

QueueProcessThread = Task.Factory.StartNew(() => UpdateWaveFormCollections(WaveForms), tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);

更新在循环中运行的集合的代码(为简洁起见,省略了一些代码行):

waveForm.LastDisplayedTimeStamp = DateTime.Now; // move the last displayed time up

int collectionSize = waveForm.WaveData.Count; 
while (waveForm.WaveDataBuffer.Count > 0 && waveForm.WaveDataBuffer.Peek().TimeStamp < waveForm.LastDisplayedTimeStamp)
{
   if (waveForm.CurrentPosition >= collectionSize)
   {
      waveForm.CurrentPosition = 0;
   }
   waveForm.WaveData[waveForm.CurrentPosition] = waveForm.WaveDataBuffer.Dequeue();
   waveForm.CurrentPosition++;
}

如您所见,我实际上并没有在集合中添加/删除项目,而是只是在特定位置更新项目。这是因为我希望它看起来像医院里的病人监护仪。

我遇到的问题是我意识到我正在非 UI 线程上更新此集合,并且该集合直接绑定到 Infragistics LineSeries ......这是有效的。但是,当我在预期的非 UI 线程上更新该集合时,使用 Infragistics StepLineSeries 的另一个图表会引发异常。我怎么可能在非 UI 线程上更新绑定的集合?我对此感到担忧,因为 1) 有时我确实会收到无法在非 UI 线程上更新集合的错误,以及 2) 当我通过调度程序将波形更新切换到 UI 线程时,GUI 的性能太差了无法使用。我需要了解为什么会这样,所以我知道如何进行。我不想部署由于我的线程管理不善而随时可能失败的应用程序。我正在寻找可能的原因,为什么/如何在非 UI 线程上更新绑定的 ObservableCollection。任何帮助/建议将不胜感激。

4

3 回答 3

3

也许您需要考虑使用 Dispatcher(除非您的代码的一部分被省略)。

当您执行需要在 UI 线程上执行代码的操作时,可以使用 Dispatcher 方法。

也许您可以在后台工作线程中检索该数据,并在更新集合时将更改传播回 UI 线程

例如

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
  new Action(() => methodHere = 50));
于 2013-02-13T14:22:27.133 回答
1

尝试使用调度程序调用以确保将通过 UI 线程访问集合,从而不允许任何其他事件在非 UI 线程上触发。

Application.Current.Dispatcher.BeginInvoke(new Action(()=>
{
// code here to access collection
}));
于 2013-02-13T14:20:31.347 回答
0

我一直在寻找的答案是您可以更新数据绑定对象的属性,而 WPF 将为您处理调度,但是,您无法从非 UI 线程更新集合(添加/删除/清除)。在我的波形中,我没有添加点,而是在特定索引处更新项目的值。然而,在另一种情况下,我总是添加和删除点。

于 2013-04-04T15:23:22.183 回答