Damo
Damo

Reputation: 2070

Dispatcher between classes

Learning C#, WPF. Currently trying to get to grips with Dispatchers, specifically between threads and other classes.

I got my dispatcher to work when in the 'MainWindow' class, but when I separate it out as below into another class I get the compile error message "The type 'System.Windows.Threading.Dispatcher' has no constructors defined"

Clearly a basic learning error, but I can't figure it out. Code below, a push in the right direction please :)

namespace threading_dispatcher_learn
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        public delegate void MyDel();

        public MainWindow()
        {
            InitializeComponent();

            label1.Content = "Label1";

            this.label2.Content = this.Dispatcher.Thread.ManagedThreadId;


            Myupdator updateclass = new Myupdator();


            Thread MyNewThread;


            MyNewThread = new Thread(updateclass.UpdateLabel);
            MyNewThread.Start();


        }



        private void button1_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Clicked");
        }

    }

    public class Myupdator
    {

        public void UpdateLabel()
        {
            MainWindow.MyDel del1 = delegate()
            {

                try
                {
                   // label1.Content = "Update 2";
                    //Thread.Sleep(3000);
                    MessageBox.Show("Message 2");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            };

           /* Now removed
             Dispatcher myDispather = new Dispatcher();
            myDispather.BeginInvoke(DispatcherPriority.Normal, del1);
*/
        //now added
        Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Normal, del1);
        Dispatcher.CurrentDispatcher.InvokeShutdown();

        }
    }

}

UPDATE: Code modified above, is this the correct way? Am I understanding you correctly? Although nothing in 'del1' is getting called.

Upvotes: 1

Views: 3680

Answers (1)

Jon
Jon

Reputation: 437386

You are not supposed to create a Dispatcher instane using a constructor. To access the Dispatcher for the current thread (or create a new one if one does not already exist) simply get the value of Dispatcher.CurrentDispatcher. Do not forget to shut down the dispatcher (e.g. with Dispatcher.InvokeShutdown) when it's no longer needed.

However, why are you doing this? In the overwhelming majority of cases, creating a Dispatcher is the wrong thing to do. Dispatcher models a Windows message loop, so it's only meaningful on UI threads.

Update: It seems that you are simply trying to modify the contents of the label and show a dialog box. You must not create a new Dispatcher for this; instead, use the Dispatcher already created on your UI thread. You need to pass to your new thread the value of Dispatcher.CurrentDispatcher as taken from your main thread, or alternatively you need to pass a reference to any UI control (e.g. a label, or the window itself).

For example:

var mainWindow = ... ; // you need to pass this to your new thread somehow
mainWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, del1);

Let me repeat the rule of thumb once again: unless you have extensive experience in multithreaded applications, creating a new Dispatcher is always the wrong thing to do.

Upvotes: 3

Related Questions