C#与Monitor-class的多线程问题 - 可能的生命周期?

时间:2009-03-13 13:11:48

标签: c# multithreading deadlock monitor

我有一些代码,我无法弄清楚。问题是该程序是多线程的,并且有一些应该同步的代码,所以我写了这个:

lock (lockObject)
{
   if (!Monitor.TryEnter(lockObject))
     Monitor.Wait(lockObject);

   //do stuff...
   Monitor.PulseAll(lockObject);
}
Monitor.Exit(lockObject);

我遇到的问题是,在某些时间点,所有线程似乎都在睡觉 - 有人能说出原因吗?程序一直在无休止地运行几乎没有cpu,但没有工作 - 在跟踪程序时我发现在某些时候没有线程处于活动状态,但是很多线程正在休眠。我知道错误主要是(在开发人员的情况下 - 总是)在显示器前面0.5米 - 但我自己无法弄清楚...可能在几分钟内;)

有人可以向我解释一下 - 提前谢谢。

3 个答案:

答案 0 :(得分:3)

我在说第一个锁定语句是拼写错误,你的意思是锁(lockObject)(小写)。

我认为你在这里误解了一点。代码中的if块永远不会成立。原因是lock(lockObject)实际上是对以下

的扩展
Monitor.Enter(lockObject);
try {
...
} finally{ 
Monitor.Exit(lockObject);

因此,当你点击if块时,你已经拥有了锁,而TryEnter应该总是成功。

答案 1 :(得分:1)

LockObjectlockObject之间有区别吗?目前尚不清楚......

然而!如果它们是不同的对象,那么首先:你没有Wait在你没有的锁上...... TryEnter只会在你指定超时时返回false。这段代码到底想要做什么?

如果没有更多背景信息,PulseAllWait的设计目标并不完全清楚;例如,here它们用于在队列太满(Wait)时阻塞队列,或者在空间可用时释放它(PulseAll)等。它很难调试线程之间没有完全交互的线程代码。

听起来你可能只需要:

lock (lockObject)
{
    // do stuff
}

我可以看到两个直接的问题;首先,你总是释放你所采取的锁(即例外)并不明显。尝试使用lock Enter/Exit - 它会正确使用。

二;如果所有线程都调用Wait ...谁会唤醒他们?他们在等什么 ?如上所述:是的,他们都会无限期地睡觉。

答案 2 :(得分:1)

这是一个奇怪的设置。 'LockObject'与'lockObject'相同吗?或者这是一个错字?如果它们相同,那么您的设置是多余的,因为无需在已锁定的内容上调用Monitor.TryEnter。如果'LockObject'是另一个对象,那么为什么不将Monitor.Exit移动到lock语句内?