c#中单线程无递归的奇怪死锁

本文关键字:死锁 递归 单线程 | 更新日期: 2023-09-27 17:53:02

我的c#应用程序出现了一个奇怪的行为

我通过VS2010在调试模式下运行应用程序,几个小时后,应用程序只是等待锁释放,但唯一存活的线程是等待锁释放的线程,并且在该函数中没有递归:

class ProductionNode        {  
   private readonly object _lock = new object();  
   public bool Activate( long jobId )  
   {  
       lock(_lock) // Doesn't go through here  
       {  
         return DAL.InsertJobIfNotExists(jobId)>0; //SQL PLAIN INSERT IF NOT EXIST COMMAND  
       }  
  }
  public void HasJobs()  
  {  
       lock(_lock)
       {
           return DAL.HasProductionJobs();
       }  
  }
 }    

再次,当我使用VS2010暂停应用程序时,唯一使用ProductionNode的线程是等待_lock对象被释放的线程。

为了说清楚,应用程序可能会在几个线程中激活生产节点,但是在发生死锁的给定场景中,VS只显示一个使用ProductionNode对象的线程,其他线程使用其他对象类型。

任何想法?

欢呼,Doron

c#中单线程无递归的奇怪死锁

我建议使用windbg (Windows的调试工具,包含在Windows SDK中)和psscor2来更深入地调试您的问题。

基本上,在windbg中尝试:

1。负载psscor2:

。加载C:'tools'psscor2'amd64'psscor2 [替换为存放psscor2 dll的路径]

2。尝试使用

查找哪些线程持有哪些锁

!syncblk

3。查看正在运行的线程,并与持有锁的线程进行比较

!threads

4。在线程间切换

~Xs *[where X is the thread id you got from !threads and that you are interested in because it's holding a lock]*

  1. 查看当前线程的托管调用堆栈,以找出在获得锁之前发生了什么

!clrstack -a

编辑:

因为你可能使用。net 4,你可能想使用SOSEX而不是psscor2。到目前为止,我还没有真正使用SOSEX,但是我想看看死锁命令:!dlk

一些提示可能会有所帮助。我将执行以下步骤:

  1. 右键单击_lock并找到所有使用Visual Studio参考资料上下文菜单。也许你正在使用锁在其他地方(你在你的更新)。
  2. 确保锁不是staticProductionNode类则不是singleton
  3. 你的线程可能是困在DAL.InsertJobIfNotExists所以记录入口和出口将有助于追踪问题的根源。