Reputation: 560
I have implemented a piece of code in C# which is the equivalent of a producer with many consumers using the Monitor's Wait and PulseAll methods.
I would like to provide the option for the producer to wait before producing until all consumers are waiting.
This is the simplified implementation of the consumer side:
lock (_lock)
{
while (! _condition)
{
Monitor.Wait(_lock);
}
}
And this is the simplified implementation on the producer side:
lock (_lock)
{
_condition = true;
Monitor.PulseAll(_lock);
}
This is a well known pattern which is fairly efficient and works well in my case.
In some cases I would like to be able to have the producer wait before calling the producer code above until all consumers are inside the Monitor.Wait()
call.
Let us simplify the question for the case of a single consumer.
The solution requires that the producer wait on an additional synchronization object that the consumer can signal atomically with its entrance to Monitor.Wait()
.
Generalizing the above solution, all consumers need to access a thread safe counter which is initialized with the number of consumers.
Each consumer will atomically call Monitor.Wait()
and decrement the counter. Also within the atomic call each consumer will check whether the counter is zero after the decrement and if so reinitialize the counter and signal the producer.
in a Producer and Multi-Consumer implementation in C# I need to allow the producer to wait for all Consumers to be in the waiting state before producing.
I have not found a way to implement this based on Monitors.
I would prefer a solution based on Monitors but if an entirely different approach would make this simpler, that would also be great.
Upvotes: 2
Views: 117
Reputation: 13234
You can use a CountdownEvent for this, the consumers should signal the event, then the producer can wait to enter the lock until the countdown reaches zero.
Upvotes: 1