如何诊断程序因' lock '语句而挂起的原因



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

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

我不知道如何诊断到底是什么错了。我如何知道lock语句如何影响我的程序?如果我有死锁,那么我如何捕获它?你会怎么做来找出lock中断执行的原因?

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

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

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

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

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

所以,这就是为什么lock产生死锁,而Monitor.TryEnter没有。

lock (desiredOrdersBuy)
{
    RecalculateOrdersInternal();
}

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

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

你的问题是,在注释代码你额外检查if(force)条件

最新更新