C# WPF Dispatcher.BeginInvoke和线程访问
我很难理解为什么这个简单的方法不起作用 如果我理解正确,UIElements只能由它们自己的线程更改,而后台线程不能。 尝试此代码时。它抛出: InvalidOperationException-调用线程无法访问此对象,因为其他线程拥有它 参考代码:C# WPF Dispatcher.BeginInvoke和线程访问,c#,wpf,dispatcher,C#,Wpf,Dispatcher,我很难理解为什么这个简单的方法不起作用 如果我理解正确,UIElements只能由它们自己的线程更改,而后台线程不能。 尝试此代码时。它抛出: InvalidOperationException-调用线程无法访问此对象,因为其他线程拥有它 参考代码: Canvas c = new Canvas(); RootWindow.AddChild(c); Thread r = new Thread( new ThreadStart(() =>
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();
多边形
是一个元素。因此,只能从创建它的线程访问它。您在后台线程上创建了它,因此只能从该线程访问它。当你试图从UI线程访问它时,它会对你大喊大叫
您需要在UI线程中创建对象、修改对象并将其添加到容器中。刚才显示的代码都不属于后台线程
也许,如果您需要做一些复杂的事情来生成
点
对象序列,而不是仅仅使用4个硬编码值,那么这将是可能属于后台线程的唯一部分。如果您需要查询数据库,或者执行一些昂贵的图形操作来确定这些点应该是什么,并且需要花费足够长的时间才能在UI线程中执行,那么可以让一个任务在另一个线程中生成一个列表
,然后让UI线程获取这些点,将它们放入一个多边形中
并将其添加到窗口中。System.Windows.Media.PointCollection
是一个依赖对象
。您不能在一个线程(后台线程)上实例化它,然后在另一个线程(UI线程)上使用它。