C#中的奇怪死锁,单线程且没有递归

时间:2011-04-27 08:01:18

标签: c# multithreading locking deadlock

我遇到了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对象的单个线程,其他线程使用其他对象类型。

有什么想法吗?

干杯, 多伦

2 个答案:

答案 0 :(得分:3)

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

基本上,在windbg尝试:

1。加载psscor2:

  

.load 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. 查看当前线程的托管调用堆栈,以了解在获取锁之前发生的事情
  2. !clrstack -a

    修改

    由于您可能使用.net 4,因此您可能希望使用SOSEX而不是psscor2。到目前为止我还没有真正使用过SOSEX,但是我会看看死锁命令:!dlk

答案 1 :(得分:1)

一些可能有帮助的提示。我会采取这些步骤:

  1. 右键点击_lock,找到全部 使用Visual Studio进行引用 上下文菜单。也许你正在使用 锁定在其他地方(你在更新中做过)。
  2. 确保锁定不是static 并且ProductionNode类不是 singleton
  3. 你的主题是可能的 被困在里面 DAL.InsertJobIfNotExists所以 记录它的入口和出口 将帮助追踪问题根。