gpt4 book ai didi

c# - 当线程使用调度程序并且主线程正在等待线程完成时出现死锁

转载 作者:太空狗 更新时间:2023-10-30 00:51:57 27 4
gpt4 key购买 nike

有人可以解释一下为什么会造成死锁,以及如何解决吗?

        txtLog.AppendText("We are starting the thread" + Environment.NewLine);

var th = new Thread(() =>
{

Application.Current.Dispatcher.Invoke(new Action(() => // causes deadlock
{
txtLog.AppendText("We are inside the thread" + Environment.NewLine); // never gets printed
// compute some result...
}));


});

th.Start();
th.Join(); // causes deadlock
// ... retrieve the result computed by the thread

说明:我需要我的辅助线程计算一个结果,并将它返回给主线程。但是辅助线程也必须将调试信息写入日志;日志位于 wpf 窗口中,因此线程需要能够使用 dispatcher.invoke()。但是当我执行 Dispatcher.Invoke 时,出现了死锁,因为主线程正在等待辅助线程完成,因为它需要结果。

我需要一个模式来解决这个问题。请帮我重写这段代码。 (请编写实际代码,不要只说“使用 BeginInvoke”)。谢谢。

另外,从理论上讲,我不明白一件事:只有当两个线程以不同的顺序访问两个共享资源 时,才会发生死锁。但在这种情况下,实际资源是什么?一个是图形用户界面。但另一个是什么?我看不到它。

通常通过强加线程只能以精确顺序锁定资源的规则来解决死锁。我已经在其他地方做过了。但在这种情况下,我该如何实现此规则,因为我不了解实际资源是什么?

最佳答案

简短回答:使用 BeginInvoke() 而不是 Invoke()。长答案会改变您的方法:查看备选方案。

当前您的 Thread.Join() 导致主线程被阻塞等待辅助线程的终止,但辅助线程正在等待主线程执行您的 AppendText 操作,因此您的应用程序陷入僵局.

如果您更改为 BeginInvoke(),那么您的辅助线程将不会等到主线程执行您的操作。取而代之的是,它将对您的调用进行排队并继续。您的主线程不会在 Join() 上阻塞,因为这次您的辅助线程已成功结束。然后,当主线程完成时,此方法将可以自由处理对 AppendText 的排队调用

备选方案:

void DoSomehtingCool()
{
var factory = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());
factory.StartNew(() =>
{
var result = await IntensiveComputing();
txtLog.AppendText("Result of the computing: " + result);
});
}

async Task<double> IntensiveComputing()
{
Thread.Sleep(5000);
return 20;
}

关于c# - 当线程使用调度程序并且主线程正在等待线程完成时出现死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24211934/

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