アップデート
私はこの問題を解決しました。線とグラフのオブジェクトへのアクセスを適切に同期していないことがわかりました。ハンドラーの期間中それらをロックする代わりに、私はそれらが使用された瞬間だけそれらをロックしました。Dynamic Data Displayライブラリ内の何かが、遅延実行を使用していて、予期していなかったときにオブジェクトの1つにアクセスしようとしていたと思います。
TL; DR:ロックを適切に同期します。
私は現在、WPFを使用していくつかのクラスライブラリのアルゴリズムを視覚化するGUIに取り組んでいます。GUI内で使用しているすべてのコントロールは、標準のWPFまたはMicrosoft DynamicDataDisplayライブラリからのものです。
非常に一般的な「別のスレッドがオブジェクトを所有しているため、呼び出し元のスレッドはこのオブジェクトにアクセスできません」というエラーが発生します。私はかなりの量の検索を行いましたが、これに対する解決策を自分で見つけることができません。
今のところ、スレッドがチャートを所有していない場合にチャートに線を追加する方法について少し混乱しています。このサイトの他の多くの回答が示唆しているように、ディスパッチャを使用してみましたが、これは解決されていません。
サマリーウィンドウは、シミュレーションが実行される前に開き、データをリアルタイムで表示するメインウィンドウの子ウィンドウとなることを目的としています。
シミュレーターは、すべて非同期で処理される多数のイベントを公開します(内部的には、BeginInvokeとEndInvokeを使用します)。これはこのシナリオで問題を引き起こす可能性がありますか?
サマリービューモデルは、多数のビジュアライゼーションを登録します。ビジュアライゼーションは、独自のコントロールを作成し、サマリーウィンドウによって提供されるキャンバスに追加します。
コードの非常に簡単な概要を以下に示します
public class MainWindowModel
{
//...
public async void RunSimulation()
{
WindowService.OpenWindowFor<SimulationSummaryViewModel>(SimSummaryVM);
await Simulator.Run();
}
}
public class SimulatorSummaryViewModel
{
//...
public SimulatorSummaryViewModel()
{
Visualisations.Add(new RealTimeChart());
}
//...
}
public class RealTimeChart : IVisualisation
{
// ...
private ChartPlotter _Chart; //From Dynamic Data Display library
//Handles adding information to the current line
private void OnSimulatorStepHandler(Args a)
{
/* The exception occurs in here, when adding a data point,
whilst another handler is adding a line to the chart.
I have tried adding a lock to the chart and line objects, but it had no effect
*/
}
//Handles adding the current line to the chart
private void OnSimulatorRepetitionComplete(Args a)
{
//lineToAdd is an EnumerableDataSource<DataPoint>.
//DataPoint is a simple class with two primitive properties.
_Chart.Dispatcher.Invoke(new Action(()=>
{
_Chart.AddLineGraph(lineToAdd);
}));
}
}
public class SummaryWindow : Window
{
// ...
public SummaryWindow()
{
// ...
foreach(IVisualisation Vis in ViewModel.Visualisations)
{
Vis.Draw(this.VisCanvas);
}
}
}