我有一些代码,我无法弄清楚。问题是该程序是多线程的,并且有一些应该同步的代码,所以我写了这个:
lock (lockObject)
{
if (!Monitor.TryEnter(lockObject))
Monitor.Wait(lockObject);
//do stuff...
Monitor.PulseAll(lockObject);
}
Monitor.Exit(lockObject);
我遇到的问题是,在某些时间点,所有线程似乎都在睡觉 - 有人能说出原因吗?程序一直在无休止地运行几乎没有cpu,但没有工作 - 在跟踪程序时我发现在某些时候没有线程处于活动状态,但是很多线程正在休眠。我知道错误主要是(在开发人员的情况下 - 总是)在显示器前面0.5米 - 但我自己无法弄清楚...可能在几分钟内;)
有人可以向我解释一下 - 提前谢谢。
答案 0 :(得分:3)
我在说第一个锁定语句是拼写错误,你的意思是锁(lockObject)(小写)。
我认为你在这里误解了一点。代码中的if块永远不会成立。原因是lock(lockObject)实际上是对以下
的扩展Monitor.Enter(lockObject);
try {
...
} finally{
Monitor.Exit(lockObject);
因此,当你点击if块时,你已经拥有了锁,而TryEnter应该总是成功。
答案 1 :(得分:1)
LockObject
和lockObject
之间有区别吗?目前尚不清楚......
然而!如果它们是不同的对象,那么首先:你没有Wait
在你没有的锁上...... TryEnter
只会在你指定超时时返回false。这段代码到底想要做什么?
如果没有更多背景信息,PulseAll
和Wait
的设计目标并不完全清楚;例如,here它们用于在队列太满(Wait
)时阻塞队列,或者在空间可用时释放它(PulseAll
)等。它很难调试线程之间没有完全交互的线程代码。
听起来你可能只需要:
lock (lockObject)
{
// do stuff
}
我可以看到两个直接的问题;首先,你总是释放你所采取的锁(即例外)并不明显。尝试使用lock
Enter/Exit
- 它会正确使用。
二;如果所有线程都调用Wait
...谁会唤醒他们?他们在等什么 ?如上所述:是的,他们都会无限期地睡觉。
答案 2 :(得分:1)
这是一个奇怪的设置。 'LockObject'与'lockObject'相同吗?或者这是一个错字?如果它们相同,那么您的设置是多余的,因为无需在已锁定的内容上调用Monitor.TryEnter。如果'LockObject'是另一个对象,那么为什么不将Monitor.Exit移动到lock语句内?