Reputation: 2070
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
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