我很难理解为什么这个简单的方法不起作用 如果我理解正确,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();
答案 0 :(得分:1)
Polygon
是一个UIElement。因此,只能从创建它的线程访问它。您在后台线程上创建了它,因此只能从该线程访问它。当你试图从UI线程访问它时,它会对你大喊大叫。
您需要在UI线程中创建对象,对其进行修改并将其添加到容器中。您刚刚显示的代码都不属于后台线程。
也许,如果你需要做一些复杂的事情来生成Point
个对象的序列,而不是仅使用4个硬编码值,那么这将是可能所属的唯一部分在后台线程中。如果您需要查询数据库,或者执行一些昂贵的图形操作来确定点应该是什么,并且需要足够长的时间才能在UI线程中执行它,那么请创建一个生成{{1}的任务在另一个线程中,然后让UI线程获取这些点,将它们放入List<Point>
并将其添加到窗口。