0

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

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

我不明白如何诊断到底出了什么问题。我怎么知道lock语句如何影响我的程序?如果我有死锁,那我怎么能抓住它?你会怎么做才能找出为什么lock会中断执行?

4

2 回答 2

4

好的,要诊断此问题,您需要Threads在调试时使用该窗口。这将允许您在正在运行的线程之间切换并查看每个线程的位置。显然,另一个线程对该对象具有排他锁,如果您在语句上放置一个断点lock并在尝试执行该语句Threads 之前lock查看另一个线程,我相信您会发现另一个线程锁定该对象。

注意:要打开线程窗口,您的应用程序实际上必须正在运行。

现在,为了澄清 和 之间的区别Monitor.TryEnterlock根据MSDN 文档Monitor.TryEnter肯定是不同的:

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

此方法类似于 Enter,但它永远不会阻塞。如果线程不阻塞就无法进入,该方法返回false,线程不进入临界区。

因此,这就是为什么lock会产生死锁但Monitor.TryEnter不会产生死锁的原因。

于 2012-12-26T12:28:06.077 回答
0
lock (desiredOrdersBuy)
{
    RecalculateOrdersInternal();
}

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

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

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

于 2012-12-26T12:26:26.353 回答