根据文章 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 线程上同步处理。您可以做的最糟糕的事情是竞争条件,它不会破坏任何共享状态。
移除锁定,代码仍应按预期工作。
我不太愿意提供任何示例代码,因为我不知道您要通过此示例实现什么目标。
