Yes, the producer (or inserter) will be blocked while the lock is held by the consumer. Note that the lock is released by a call to Monitor.Wait
and then reacquired when control flow has returned back to the caller. All of this assumes your producer attempts to acquire the same lock.
As a side note, the way you have the consumer coded is slightly less efficient than it could be. Because you have a continue
statement I have to assume that a while
loop wraps the lock
which probably makes your code look more like the following.
object msg = null;
while (msg == null)
{
lock (MsgQueue)
{
if (MsgQueue.Count == 0)
{
Monitor.Wait(MsgQueue);
continue;
}
msg = MsgQueue.Dequeue();
}
}
This could be refactored so that the wait condition is rechecked inside the lock
block. This way you do not have to release and reacquire the lock to perform the check.
object msg = null;
lock (MsgQueue)
{
while (MsgQueue.Count == 0)
{
Monitor.Wait(MsgQueue);
}
msg = MsgQueue.Dequeue();
}
Again, because I see the continue
statement I am assuming you are aware that the wait condition must always be rechecked after a Wait
. But, just in case you are not aware of this requirement I will state it here because it is important.
If the wait condition is not rechecked and there is 2 or more consumers then one of them could get inside the lock and dequeue the last item. This could still happen even if the other consumer were moved from the waiting queue to the ready queue via a call to Pulse
or PulseAll
, but it did not get a chance to reacquire the lock before the first consumer. Obviously, without the recheck a consumer could attempt to operate on an empty queue. It does not matter whether Pulse
or PulseAll
is used on the producing side. There is still a problem because the Monitor
does not give preference to a Wait
above an Enter
.
Update:
I forgot to point out that if you are using .NET 4.0 then you can take advantage of BlockingCollection which is an implementation of a blocking queue. It is safe for multiple producers and consumers and does all of the blocking for you if the queue is empty.