繁体   English   中英

WPF Dispatcher.Begin调用和线程访问

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM