gpt4 book ai didi

c# - 为什么 WPF 的 Dispatcher.Invoke 在主线程上运行时不会导致死锁?

转载 作者:行者123 更新时间:2023-11-30 13:54:21 24 4
gpt4 key购买 nike

考虑代码:

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");
}
}

当然,button_Click是运行在主线程上的。

我的理解是 button.Dispatcher.Thread 是主线程,Invoke() 只有在线程未被阻塞时才会被处理。但是,这种情况下主线程不是被阻塞了吗? IE。主线程正在等待 Dispatcher.Invoke() 调用完成,而 Dispatcher.Invoke() 正在等待主线程释放。所以我预计这里会出现死锁,但它并没有陷入僵局。

为什么?

P.S:我知道在这种情况下我不需要 Dispatcher.Invoke 并且我可以直接调用 button.Content = "1234"。我试图理解为什么在这种情况下不会发生死锁。

最佳答案

我相信您的误解可能基于以下思考过程:

“嗯,Invoke 会阻塞调用线程,直到操作完成。如果线程被阻塞,它如何在线程上执行操作?”

如果我们查看源代码,我们会发现回调不仅在同一个线程上被调用,而且直接*在 Invoke 方法中被调用。主线程没有被阻塞。 p>

如果您查看调度员的 Reference Source页面,您可以在 if 上方看到以下评论Invoke 内的声明方法的实现,在其中调用回调:

// 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 */
}

您正在调用 Dispatcher.Invoke在主线程上,该方法通过立即调用它来处理。

*嗯,不是直接,而是Invoke(Action)的整个主体只是调用上面代码所在的方法。

关于c# - 为什么 WPF 的 Dispatcher.Invoke 在主线程上运行时不会导致死锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43364132/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com