根据文章 Lock Up Unlocked 对死锁的 C# Windows 窗体应用程序实现更改后我仍然遇到与文章Locked Up!之前的代码中相同的问题
也就是说,快速单击按钮几次后,应用程序就会挂起(变得无响应)。
为什么?
以及如何纠正呢?
using System;
using System.Windows.Forms;
using System.Threading;
namespace LockupUnlocked
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
_t = new Thread(new ParameterizedThreadStart(WorkerThread));
}
private Thread _t;
private object lockObject = new object();
private bool StopThread = false; ////changes added to avoid deadlock
private void WorkerThread(object sender)
{
Thread.Sleep(1000);
//while (true)
while (!StopThread)//changes added to avoid deadlock
{
string result = "This is a Test";
IAsyncResult aResult;////changes added to avoid deadlock
lock (lockObject)
{
Thread.Sleep(25);
//lblResult.Invoke(new MethodInvoker(delegate { lblResult.Text = result; }));
aResult = lblResult.BeginInvoke//changes to avoid deadlock
(new MethodInvoker(delegate { lblResult.Text = result; }));
}
lblResult.EndInvoke(aResult);//changes added to avoid deadlock
Thread.Sleep(500);
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
StopThread = true;
}
private void Form1_Load(object sender, EventArgs e)
{
_t.Start();
}
private void button1_Click(object sender, EventArgs e)
{
lock (lockObject)//changes added to avoid deadlock
{
lblResult.Text = "Override the Test";
}
}
}
}
最佳答案
对我来说,这看起来像是锁争用,不一定是死锁。
每 25 毫秒(不是 25 秒,而是 25000)迭代一次 while 循环,单击按钮将中断此请求锁定,可能永远不会获得该锁定,因为 sleep 位于锁定范围内.
如果不单击按钮,这似乎可以工作,但是,等待锁定的按钮单击将阻塞 UI 线程,导致出现“未响应”消息,因为表单没有可用时间来绘制自身.
您实际上不需要锁定来更新文本值。当您从 Control
调用时,它只是将消息推送到 UI 消息队列,该消息在 UI 线程上同步处理。您能做的最糟糕的事情就是竞争条件,它不会破坏任何共享状态。
删除锁定,代码仍应按您的预期工作。
我不太愿意提供任何示例代码,因为我不知道您想通过此示例实现什么目的。
关于c# - 为什么 Windows 窗体应用程序 (C#) 会死锁以及如何避免死锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15086026/