私はしばらくの間、マルチスレッドの問題に取り組んできました。過去数日間、すべての呼び出しがスレッドセーフであることを確認しようと努めてきました。私はちょうど私を投げた問題に遭遇しました. シナリオは次のとおりです。
~500 ポイント/秒/波形が渡される Infragistics XamDataChart コントロールを使用して、波形をプロットしようとしています。アプリケーションの起動時に、WaveData という名前の ObservableCollection プロパティを持つオブジェクトを作成します。これらのプロパティは、items コントロールの 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を更新できる理由/方法を探しています。ヘルプ/提案をいただければ幸いです。