ReaderWriterLockSlim and Pulse / Wait
Is there an equivalent to Monitor.Pulse
and Monitor.Wait
that I can use in conjunction with ReaderWriterLockSlim
?
I have a class where I have encapsulated multi-threaded access to the main queue. To do something on the queue, I acquire a lock that protects the main queue (and a couple of other objects), then adds an item and a Monitor.Pulse
blocked object to signal that something has been added to the queue.
public void Enqueue(ITask task)
{
lock (mutex)
{
underlying.Enqueue(task);
Monitor.Pulse(mutex);
}
}
At the other end of the queue, I have one background thread that continuously processes messages as they enter the queue. It uses Monitor.Wait
when there are no items in the queue to avoid unnecessary polling. (I think this is a good design, but any flame (within reason) is appreciated if they help me know otherwise.)
private void DequeueForProcessing(object state)
{
while (true)
{
ITask task;
lock (mutex)
{
while (underlying.Count == 0)
{
Monitor.Wait(mutex);
}
task = underlying.Dequeue();
}
Process(task);
}
}
As more operations are added to this class (read-only access to secured locks is required) someone suggested using ReaderWriterLockSlim
. I have never used this class before, and assuming it might provide some benefit, I don't mind, but only if I can keep the Pulse / Wait design.
a source to share
After playing around a bit (and after accepting the call to Mark (I agree, my change is not entirely basic)) I came up with this combination:
ReaderWriterLockSlim rwls;
AutoResetEvent are;
public void Enqueue(ITask task) {
rwls.EnterWriteLock();
try {
underlying.Enqueue(task);
if (underlying.Count == 1) {
are.Set();
}
} finally {
rwls.ExitWriteLock();
}
}
private void DequeueForProcessing(object state) {
while (true) {
ITask task;
rwls.EnterWriteLock();
try {
while (underlying.Count == 0) {
rwls.ExitWriteLock();
are.WaitOne();
rwls.EnterWriteLock();
}
task = underlying.Dequeue();
} finally {
rwls.ExitWriteLock();
}
Process(task);
}
}
To my untrained eye, it seems like it fits the bill (although a little uglier if not sure) and it doesn't differ too much from the original version.
a source to share