我和我的团队正在开发一个显示多个并发 XamDataChart 控件的 WPF 应用程序(由 Infragistics 提供)。每个图表都绑定到一个不同的 ObservableCollection,最多可以包含 200 万个点。对于每个图表,DispatcherTimer 会定期检索要附加到集合的新项目(每 100 毫秒最多 1000 个)。每次新项目出现时,它们都会被添加到集合的“尾部”中,并且从“头部”中移除相同的数量,因此集合中的项目数量随着时间的推移保持不变。
我们面临的问题是添加/删除操作冻结了 GUI,因为集合只能由主线程修改。我们尝试了许多方法(BackgroundWorker、Application.Current.Dispatcher 和 DispatcherPriority.Background、Task.Factory 等),但似乎都没有解决问题,并且 GUI 一直冻结。
您能否就处理大量绑定数据同时保持 GUI 响应的最佳方法向我们提供建议?
更新:
1) 正如我在下面的评论中所指出的,我们已经尝试在抑制 OnCollectionChanged 的同时添加和删除项目。即使它似乎对少量数据有效果,但在我们的场景中,这种解决方案的优势实际上是无法观察到的。
2) 数据在单独的线程中准备和收集。这是一个长时间运行的操作,但没有明显的缓慢或无响应。当数据传递到图表组件进行渲染时,应用程序会冻结。
3) 以下是生成数据(在单独的线程中)并在 UI 上显示数据的方法:
private void GenerateDataButtonClick(object sender, RoutedEventArgs e)
{
Task<List<RealTimeDataPoint>> task = Task.Factory.StartNew(() => this.RealTimeDataPointGenerator.GenerateData(2000000));
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => { this.DataPoints.Clear();
this.DataPoints.AddRange(task.Result);
if (!this.StartDataFeedButton.IsEnabled)
this.StartDataFeedButton.IsEnabled = true;
}));
}
public void DispatcherTimerTick(object sender, EventArgs e)
{
Task<List<RealTimeDataPoint>> task = Task.Factory.StartNew(() => this.RealTimeDataPointGenerator.GenerateData(1000));
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => { this.DataPoints.RemoveRange(0, task.Result.Count); this.DataPoints.AddRange(task.Result); }));
}
提前致谢, 詹卢卡