【发布时间】:2011-07-29 06:09:45
【问题描述】:
我有一种情况,有时在Monitor.PulseAll(object lock) 命令上没有唤醒睡眠线程。这种现象不是确定性的。一般来说它可以工作,但有时在调试期间,睡眠线程无法唤醒,我的队列不断填满。
如果队列为空,则工作线程进入睡眠状态:
private void Dequeue()
{
try
{
while (true)
{
T item;
lock (_lock)
{
if (_queue.Count == 0)
{
Monitor.Wait(_lock); //thread stays asleep here. why?
}
item = _queue.Dequeue(); //break point [1]
}
}
}
catch (ThreadAbortException ex)
{
_logger.Error(ex)
}
}
添加后,队列至少有一项,锁定对象上的PulseAll 应该唤醒线程。
public void Add(T item)
{
Validate.NotNull(item, "item must not be null");
lock (_lock)
{
_queue.Enqueue(item);
_queueInfoAdministrator.IncrementCount();
Monitor.PulseAll(_lock);
}
}
是否有其他人有类似的经历或可以为我指出正确的方向,为什么会发生这种情况(有时)?
编辑 2011.04.08:
更多信息 - 只有一个消费者线程。所以理论上 Pulse 就足够了。一旦达到状态,消费者线程保持睡眠状态,我可以继续将项目排入队列并随后调用PulseAll,而无法唤醒睡眠线程。我放置了一个断点 [1],它在所描述的情况下永远不会被击中。因此,我相信这不是 MSDN 页面中描述的 Pulse/Monitor 死锁问题。
【问题讨论】:
-
Monitor.Wait 释放锁 Daniel.
-
你是对的,我不知道。
-
@Hans Passant - 我看不出这个问题/答案如何适用于此。正如您在给定答案中建议的那样,我确实在队列对象周围有一个
lock。 -
那个问题是关于 exact 相同的代码。使用或丢失它,由您决定。
标签: c# multithreading