【发布时间】:2013-02-22 14:59:41
【问题描述】:
我再次遇到此错误:调用线程无法访问此对象,因为另一个线程拥有它。
这是我的代码:
public void InitiateSignalAnalysisPlot()
{
if (_nActiveChannel > 0) // timeDomainPlotter init
{
_dataX = new List<double[]>();
_dataY = new List<double[]>();
_dataX3 = new List<List<double[]>>();
_dataY3 = new List<List<double[]>>();
double[] dataXOneCh = new double[1];
double[] dataYOneCh = new double[1];
dataXOneCh[0] = 0;
dataYOneCh[0] = 0;
CirclePointMarker pm = new CirclePointMarker { Size = 5, Fill = Brushes.Transparent };
for (int i = 0; i < _nActiveChannel; i++)
{
if (_nActiveStatsOneChannel > 0)
{
for (int j = 0; j < _nActiveStatsOneChannel; j++)
{
_dataX.Add(dataXOneCh); // data x-y mapping init
_dataY.Add(dataYOneCh);
EnumerableDataSource<double> xOneCh = new EnumerableDataSource<double>(dataXOneCh);
EnumerableDataSource<double> yOneCh = new EnumerableDataSource<double>(dataYOneCh);
xOneCh.SetXMapping(xVal => xVal);
yOneCh.SetXMapping(yVal => yVal);
CompositeDataSource dsOneCh = new CompositeDataSource(xOneCh, yOneCh);
Action InitiatePlotter = delegate()
{
LineAndMarker<MarkerPointsGraph> lam = timeDomainPlotter.AddLineGraph(dsOneCh,
new Pen(pm.Fill, 2),
pm,
new PenDescription("C" + Convert.ToString(i) + "S" + Convert.ToString(j)));
};
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, InitiatePlotter);
}
_dataX3.Add(_dataX);
_dataY3.Add(_dataY);
}
}
timeDomainPlotter.FitToView();
}
else
{
return;
}
}
错误发生在"this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, InitiatePlotter);"
这是由主窗口线程调用的 WPF 窗口后面的一段代码。我很困惑我使用 dispatcher.invoke() 来取消这个多线程冲突,为什么我仍然收到这个错误?如果我将这段代码放入被调用窗口的构造函数中,它可以工作,但我只是不想那样做。我可以做些什么改变来避免这个错误?谢谢。
更多可能有帮助的信息: timeDomainPlotter 在 wpf 窗口 B 中,在窗口 A 中启动 (WindowB _windowB = new WindowB(); );上面的代码 InitiateSignalAnalysisPlot() 也在窗口 B 中,但在窗口 A 中调用了 InitiateSignalAnalysisPlot(),类似于 _windowB,InitiateSignalAnalysisPlot();
如果我不 Dispatcher.Invoke() 它,也会有一个异常,即The calling thread must be STA, because many UI components require this.,发生在
LineAndMarker<MarkerPointsGraph> lam = timeDomainPlotter.AddLineGraph(dsOneCh,
new Pen(pm.Fill, 2),
pm,
new PenDescription("C" + Convert.ToString(i) + "S" + Convert.ToString(j)));
【问题讨论】:
-
也许检查您是否需要使用 Dispatcher.CheckAccess() 调用它
-
当我输入 Dispatcher 时,没有自动弹出 CheckAccess() 方法.....
-
它就在那里;出于某种原因,Microsoft 决定将 Dispatcher.CheckAccess() 和 Dispatcher.VerifyAccess() 设置为不显示在智能感知(属性/方法/等的弹出列表)中。如果您继续输入它,它将编译。也就是说,这里的 CheckAccess() 实际上不会告诉你任何你不知道的事情。
-
是的,Dispatcher.CheckAccess() 返回 false。这是什么意思?
-
这意味着当您调用 Dispatcher.CheckAccess() 时,该调用在“错误”线程上运行,即不是 Dispatcher 正在管理的线程。但是你已经知道了,因为这就是你得到例外的原因。 CheckAccess() 方法只是一种提前检查的方法,而不是找出异常发生的时间。这不是新信息,对您没有任何帮助。
标签: c# wpf multithreading