c# - 为什么 Windows 窗体应用程序 (C#) 会死锁以及如何避免死锁?

标签 c# multithreading debugging synchronization deadlock

根据文章 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/

相关文章:

oracle - 仅在调试时出现 : java. io.IOException:现有连接被远程主机强制关闭

c# - EF Core 选择一个由相关实体过滤的实体

java - Java 中的线程安全多线程

java - Spring中使用@Async和@Scheduled时检测线程状态

c++ - 在 C++ 中附加到另一个进程

Javascript 数组错误 - 通过更改一个数组,所有其他数组都会更改

c# - 防止 C# 子类覆盖方法

c# - 完全在代码隐藏中创建 DataGrid 列工具提示

c# - 如何检查字符串是否包含特定 unicode 范围内的所有字符?

c++ - boost 线程 : is it possible to limit the run time of a thread before moving to another thread