[英]WPF Dispatcher.BeginInvoke and thread access
我很难理解为什么这个简单的方法不起作用如果我理解正确,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();
Polygon
是一个UIElement。 因此,只能从创建它的线程中访问它。 您是在后台线程上创建的,因此只能从该线程访问它。 当您尝试从UI线程访问它时,它会大吼大叫。
您需要在UI线程中创建,修改对象并将其添加到容器中。 您刚刚显示的代码都不属于后台线程。
也许,如果您需要做一些复杂的事情来生成Point
对象的序列,而不是仅使用4个硬编码值,那么那将是唯一可能属于后台线程的部分。 如果您需要查询数据库,或者执行一些昂贵的图形操作来确定点应该是什么,并且花费了很长时间以至于您无法在UI线程中完成操作,那么可以执行一个生成List<Point>
的任务在另一个线程中,然后让UI线程获取这些点,将它们放入“ Polygon
然后将其添加到窗口中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.