SYSK 348: InvokeRequired No More…


By now, we all have learned to call Control.InvokeRequired to avoid the following error when updating UI from another thread or calling other apartment threaded objects that expect to be called on a thread they were created on:


 


The calling thread cannot access this object because a different thread owns it.


 


In WPF though, the way to do same is as follows:



  1. Instead of calling Control.InvokeRequired, call Control.CheckAccess

  2. Use Control.Dispatcher.Invoke or BeginInvoke if CheckAccess returned false

 


Below is a simple example of doing just that:


 


using System;


using System.Windows;


 


namespace WPFWinApp


{


    public partial class Window1 : System.Windows.Window


    {       


        public Window1()


        {


            InitializeComponent();


        }


 


        void StartThread(object source, EventArgs e)


        {        


            System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(DoWork));


        }


 


        void DoWork(object param)


        {


           


            try


            {


                if (base.CheckAccess() == true)


                    this.label1.Content = DateTime.Now.ToLongTimeString();


                else


                    base.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,


                        new System.Threading.WaitCallback(DoWork), param);


            }


            catch (Exception ex)


            {


                System.Windows.MessageBox.Show(ex.Message);


                System.Diagnostics.Debug.WriteLine(ex.Message);


            }


        }


    }


}

Comments (2)

  1. Anonymous says:

    Maybe using System.Threading.SynchronizationContext is more elegant?

  2. 1. should be

    Instead of calling Control.InvokeRequired, call Control.Dispatcher.CheckAccess()

Skip to main content