0

このエラーが再び発生します。別のスレッドがオブジェクトを所有しているため、呼び出し元のスレッドはこのオブジェクトにアクセスできません。

これが私のコードです:

 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にありますが、InitiateSignalAnalysisPlot()はウィンドウAで呼び出され、_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)));
4

1 に答える 1

1

timeDomainPlotterはどこで作成しますか?

異なるスレッドで作成されたコントロールには、異なる Dispatcher があります。「this.Dispatcher」を介してデリゲートを呼び出しているため、このエラーが発生していると思いますが、そのデリゲート内で触れているコントロールは別のスレッドで作成されたため、別のディスパッチャーを持っています'これ'。

別のスレッドにある場合は、作成用のデリゲートを設定し、this.Dispatcher を介してそのデリゲートを呼び出すと、後でアクセスしようとしている同じスレッドでコントロールが作成されます。

于 2013-02-22T15:26:09.363 に答える