私のチームと私は、(Infragisticsによる)複数の同時XamDataChartコントロールを表示するWPFアプリケーションを開発しています。各グラフは、最大200万ポイントを含むことができる異なるObservableCollectionにバインドされています。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); }));
}
よろしくお願いします、Gianluca