如何诊断程序因“锁定”声明而挂起的原因?

时间:2012-12-26 12:19:06

标签: c# multithreading locking

在下面的代码中,当我取消注释注释代码时,我的程序行为不正确。

    private void RecalculateOrders(bool force)
    {
        //if (force)
        //{
        //    lock (desiredOrdersBuy)
        //    {
        //        RecalculateOrdersInternal();
        //    }
        //}
        //else
        //{
            if (Monitor.TryEnter(desiredOrdersBuy))
            {
                try
                {
                    RecalculateOrdersInternal();
                }
                finally
                {
                    Monitor.Exit(desiredOrdersBuy);
                }
            }
        //}
    }

我不明白如何诊断究竟是什么问题。我怎么知道lock语句如何影响我的程序?如果我有死锁,那怎么能抓住它呢?你会怎么做才能找到lock打破执行的原因?

2 个答案:

答案 0 :(得分:4)

好的,为了诊断这个问题,你需要在调试时使用Threads窗口。这将允许您在运行的线程之间切换并查看每个线程的位置。显然,另一个线程对此对象具有独占锁定,如果您在lock语句上放置断点并在尝试执行{{1}之前查看另一个Threads 我确定你会找到另一个锁定该对象的线程。

注意:打开应用程序实际必须运行的“线程”窗口。

现在,为了澄清lockMonitor.TryEnter之间的差异,根据MSDN Documentationlock肯定是不同的:

  

如果成功,此方法获取obj参数的独占锁。无论锁是否可用,此方法都会立即返回。

     

此方法类似于Enter,但它永远不会阻止。如果线程无法在不阻塞的情况下进入,则该方法返回false,并且该线程不会进入临界区。

因此,这就是Monitor.TryEnter产生死锁但lock没有产生死锁的原因。

答案 1 :(得分:0)

lock (desiredOrdersBuy)
{
    RecalculateOrdersInternal();
}

if (Monitor.TryEnter(desiredOrdersBuy))
{
    try
    {
        RecalculateOrdersInternal();
    }
    finally
    {
        Monitor.Exit(desiredOrdersBuy);
    }
}

做同样的事情。 lock(){}是Monitor.Enter / Exit的语法糖。

您的问题是,在注释代码中,您还会检查if(force)条件。