WPF thread and GUI how to access object from different thread?

匿名 (未验证) 提交于 2019-12-03 02:49:01

问题:

I have a thread that call an object that get some stuff from Internet. When this object is filled up with all information required, it raises an event with an object will all the information. The event is consumed by the controller that has started the thread.

The returned object from the event is than added into a collection that is binded the the GUI via a View Model approach.

The problem is that I can't use the CheckAccess with the binding... how can I fix the problem of using Object that has been created from an other thread of the main one?

The error that I receive when I add the object to the collection of the main thread is :

This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.

This the the controller:

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);         }     } } 

回答1:

I found the solution over this blog.

Instead of just calling the collection to add the object from the thread.

queriesViewModel.AddQuery(info); 

I have to pass the main thread to the controller and use the dispatcher. Guard answer's was very close.

    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);         }      } 


回答2:

Could a solution be to initialize the object on the main thread?

MyObject obj;  this.Dispatcher.Invoke((Action)delegate { obj = new MyObject() }); 

Edit: At a second read-through, this probably isn't a solution given your model. Are you receiving a runtime error as it is? If the object you're passing back is your own, ensuring the object is thread-safe could make CheckAccess unneccessary.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!