在下面的代码中,当我取消注释时,我的程序有不正确的行为。
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.TryEnter
和lock
之间的差异,根据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)
条件