I have a somewhat complex WPF application which seems to be 'hanging' or getting stuck in a Wait call when trying to use the dispatcher to invoke a call on the UI thread.
The general process is:
if(this.Dispatcher.Thread != Thread.CurrentThread)
{
this.Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate{
this.Name = value; // Call same setter, but on the UI thread
});
return;
}
SetValue(nameProperty, value); // I have also tried a member variable and setting the textbox.text property directly.
My problem is that when the dispatcher invoke method is called it seems to hang every single time, and the callstack indicates that its in a sleep, wait or join within the Invoke implementation.
So, is there something I am doing wrong which I am missing, obvious or not, or is there a better way of calling across to the UI thread to set this property (and others)?
Edit: The solution was to call System.Windows.Threading.Dispatcher.Run() at the end of the thread delegate (e.g. where the work was being performed) - Thanks to all who helped.
Invoke is synchronous - you want Dispatcher.BeginInvoke. Also, I believe your code sample should move the "SetValue" inside an "else" statement.
I think this is better shown with code. Consider this scenario:
Thread A does this:
lock (someObject)
{
// Do one thing.
someDispatcher.Invoke(() =>
{
// Do something else.
}
}
Thread B does this:
someDispatcher.Invoke(() =>
{
lock (someObject)
{
// Do something.
}
}
Everything might appear fine and dandy at first glance, but its not. This will produce a deadlock. Dispatchers are like queues for a thread, and when dealing with deadlocks like these its important to think of them that way: "What previous dispatch could have jammed my queue?". Thread A will come in...and dispatch under a lock. But, what if thread B comes in at the point in time at which Thread A is in the code marked "Do one thing"? Well...
You now have a beautiful deadlock.
You say you are creating a new STA thread, is the dispatcher on this new thread running?
I'm getting from "this.Dispatcher.Thread != Thread.CurrentThread" that you expect it to be a different dispatcher. Make sure that its running otherwise it wont process its queue.
I think you mean if (!this.Dispatcher.CheckAccess())
I am also geting a hang with Invoke, or if I can BeginInvoke my delegate isn't being called - seem to be doing everything by the book :-(
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With