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 线程获取这些点,将它们放入 aPolygon并将其添加到窗口中。

于 2013-05-20T19:54:06.640 回答