Consider the code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button_Click(object sender, RoutedEventArgs e)
{
//System.Threading.Thread.CurrentThread = button.Dispatcher.Thread
button.Dispatcher.Invoke(() => button.Content = "1234");
}
}
Of course, button_Click
is run on the main thread.
My understanding is that button.Dispatcher.Thread
is the main thread and the Invoke()
will get processed only when the thread is not blocked. However, isn't the main thread blocked in this case? I.e. the main thread is waiting for the Dispatcher.Invoke()
call to complete and Dispatcher.Invoke()
is waiting for the main thread to free up. So I expect a deadlock here, but it doesn't get deadlocked.
Why?
P.S: I am aware that in this situation I don't need the Dispatcher.Invoke
and that I can call the button.Content = "1234"
directly. I am trying to understand why the deadlock DOES NOT happen in this case.
I believe your misunderstanding may be based around the following thought process:
"Well, Invoke blocks the calling thread until the action is completed. How can it perform the action on the thread if the thread is blocked?"
If we look inside the source, we see that the callback is being called not only on the same thread, but directly* inside the Invoke method. The main thread is not being blocked.
If you look at the dispatcher's Reference Source page, you can see the following comment above an if
statement within the Invoke
method's implementation, with the callback being called within it:
// Fast-Path: if on the same thread, and invoking at Send priority,
// and the cancellation token is not already canceled, then just
// call the callback directly.
if(!cancellationToken.IsCancellationRequested && priority == DispatcherPriority.Send && CheckAccess())
{
/* snipped */
callback();
/* snipped */
}
You're calling Dispatcher.Invoke
on the main thread, and the method handles that by just calling it instantly.
*Well, not directly, but the entire body of Invoke(Action)
is just a call to the method that the above code is in.
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