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

16,931

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

Solution 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.

Share:
16,931
Patrick Desjardins
Author by

Patrick Desjardins

Senior Software Developer at Netflix [California, Los Gatos] Senior Software Developer at Microsoft [Washington, Redmond] Working for Microsoft Cloud and Enterprise, mostly on Team Services Dashboards, Kanban and Scaled Agile project Microsoft Teams (first release) Microsoft MVP 2013 and 2014 [Quebec, Montreal]

Updated on June 20, 2022

Comments

  • Patrick Desjardins
    Patrick Desjardins almost 2 years

    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);
            }
        }
    }
    
  • Patrick Desjardins
    Patrick Desjardins over 14 years
    This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.
  • Para
    Para almost 12 years
    Can you post the definition of UIThread in this context please? Thanks. Don't know what to substitute it with in my code
  • Jalal
    Jalal over 11 years
    It should be a subclass of System.Windows.Threading.DispatcherObject.