在下面的代码中,当我取消注释注释代码时,我的程序行为不正确。
private void RecalculateOrders(bool force)
{
//if (force)
//{
// lock (desiredOrdersBuy)
// {
// RecalculateOrdersInternal();
// }
//}
//else
//{
if (Monitor.TryEnter(desiredOrdersBuy))
{
try
{
RecalculateOrdersInternal();
}
finally
{
Monitor.Exit(desiredOrdersBuy);
}
}
//}
}
我不明白如何诊断究竟是什么问题。我怎么知道lock
语句如何影响我的程序?如果我有死锁,那怎么能抓住它呢?你会怎么做才能找到lock
打破执行的原因?
答案 0 :(得分:4)
好的,为了诊断这个问题,你需要在调试时使用Threads
窗口。这将允许您在运行的线程之间切换并查看每个线程的位置。显然,另一个线程对此对象具有独占锁定,如果您在lock
语句上放置断点并在尝试执行{{1}之前查看另一个Threads
我确定你会找到另一个锁定该对象的线程。
注意:打开应用程序实际必须运行的“线程”窗口。
现在,为了澄清lock
和Monitor.TryEnter
之间的差异,根据MSDN Documentation,lock
肯定是不同的:
如果成功,此方法获取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)
条件。