WPF线程和GUI如何从不同的线程访问对象?
我有一个线程调用一个从Internet获取一些东西的对象。 当此对象填满所需的所有信息时,它会引发一个具有对象的事件将所有信息。 该事件由启动该线程的控制器使用。
然后将事件中返回的对象添加到通过View Model方法绑定到GUI的集合中。
问题是我无法使用CheckAccess和绑定…如何解决使用从主要的其他线程创建的Object的问题?
我将对象添加到主线程集合时收到的错误是:
这种类型的CollectionView不支持从与Dispatcher线程不同的线程更改其SourceCollection。
这个控制器:
public class WebPingerController { private IAllQueriesViewModel queriesViewModel; private PingerConfiguration configuration; private Pinger ping; private Thread threadPing; public WebPingerController(PingerConfiguration configuration, IAllQueriesViewModel queriesViewModel) { this.queriesViewModel = queriesViewModel; this.configuration = configuration; this.ping = new Pinger(configuration.UrlToPing); this.ping.EventPingDone += new delPingerDone(ping_EventPingDone); this.threadPing = new Thread(new ThreadStart(this.ThreadedStart)); } void ping_EventPingDone(object sender, QueryStatisticInformation info) { queriesViewModel.AddQuery(info);//ERROR HAPPEN HERE } public void Start() { this.threadPing.Start(); } public void Stop() { try { this.threadPing.Abort(); } catch (Exception e) { } } private void ThreadedStart() { while (this.threadPing.IsAlive) { this.ping.Ping(); Thread.Sleep(this.configuration.TimeBetweenPing); } } }
我在这个博客上找到了解决方案。
而不是仅仅调用集合来从线程添加对象。
queriesViewModel.AddQuery(info);
我必须将主线程传递给控制器并使用调度程序。 警卫的答案非常接近。
public delegate void MethodInvoker(); void ping_EventPingDone(object sender, QueryStatisticInformation info) { if (UIThread != null) { Dispatcher.FromThread(UIThread).Invoke((MethodInvoker)delegate { queriesViewModel.AddQuery(info); } , null); } else { queriesViewModel.AddQuery(info); } }
解决方案是否可以初始化主线程上的对象?
MyObject obj; this.Dispatcher.Invoke((Action)delegate { obj = new MyObject() });
编辑 :在第二次阅读时,这可能不是给定模型的解决方案。 您是否收到运行时错误? 如果您传回的对象是您自己的对象,确保对象是线程安全的,可能会使CheckAccess不再需要。