更新
我已经解决了这个问题。我发现我没有正确同步对折线和图表对象的访问。我没有在处理程序期间锁定它们,而是仅在使用它们的那一刻锁定它们。我认为动态数据显示库中的某些东西正在使用延迟执行并在我没想到时尝试访问其中一个对象。
TL;DR:正确同步锁。
我目前正在开发一个使用 WPF 来可视化某个类库中的算法的 GUI。我在 GUI 中使用的所有控件要么是标准 WPF,要么来自 Microsoft Dynamic Data Display库。
我遇到了非常常见的“调用线程无法访问此对象,因为另一个线程拥有它”错误。我已经进行了大量搜索,但我自己找不到解决方案。
现在,如果线程不拥有它,我对如何在图表中添加线条有点困惑。我已经尝试使用该站点上的许多其他答案所建议的调度程序,但它并没有解决这个问题。
摘要窗口旨在作为主窗口的子窗口,在模拟运行之前打开并实时显示数据。
模拟器发布了许多异步处理的事件(在内部,它使用 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);
}
}
}