0

この単純な方法が機能しない理由を理解するのに苦労しています。正しく理解できれば、UIElements は独自のスレッドでのみ変更する必要があり、バックグラウンド スレッドは変更できません。このコードを試すとき。それはスローします:

InvalidOperationException - 別のスレッドがこのオブジェクトを所有しているため、呼び出しスレッドはこのオブジェクトにアクセスできません。

参照用のコード:

        Canvas c = new Canvas();
        RootWindow.AddChild(c);

        Thread r = new Thread( new ThreadStart(() =>
        {
            Polygon p = new Polygon();
            PointCollection pC = new PointCollection();
            pC.Add(new Point(1.5, 4.5));
            pC.Add(new Point(-7, 9));
            pC.Add(new Point(1.5, -5));
            pC.Add(new Point(10, 9));
            p.Points = pC;
            p.Stroke = Brushes.Black;
            p.Fill   = Brushes.Green;

            c.Dispatcher.BeginInvoke( DispatcherPriority.Normal , new Action( () => { c.Children.Add(p); } ));

        }));
        r.SetApartmentState(ApartmentState.STA);
        r.Start();
4

1 に答える 1

1

Polygon UIElement ですそのため、それを作成したスレッドからのみアクセスできます。バックグラウンド スレッドで作成したため、そのスレッドからのみアクセスできます。UI スレッドからアクセスしようとすると、怒鳴られます。

オブジェクトの作成、変更、コンテナへの追加は、すべて UI スレッドで行う必要があります。今示したコードは、バックグラウンド スレッドに属していません。

Pointおそらく、ハードコードされた 4 つの値を使用するだけでなく、一連のオブジェクトを生成するために何か複雑なことを行う必要がある場合、それがバックグラウンド スレッドに属する可能性のある唯一の部分になります。データベースにクエリを実行する必要がある場合、またはポイントを決定するために高価なグラフィカル操作を実行する必要があり、UI スレッドで実行できないほど時間がかかる場合はList<Point>、別のスレッドで を生成するタスクを作成し、次に、UI スレッドにそれらのポイントを取得させ、それらを に入れ、それPolygonをウィンドウに追加します。

于 2013-05-20T19:54:06.640 に答える