I have two threads, one thread processes a queue and the other thread adds stuff into the queue.
- I want to put the queue processing thread to sleep when its finished processing the queue
- I want to have the 2nd thread tell it to wake up when it has added an item to the queue
However these functions call System.Threading.SynchronizationLockException: Object synchronization method was called from an unsynchronized block of code on the Monitor.PulseAll(waiting); call, because I havent synchronized the function with the waiting object. [which I dont want to do, i want to be able to process while adding items to the queue]. How can I achieve this?
Queue<object> items = new Queue<object>();
object waiting = new object();
1st Thread
public void ProcessQueue()
{
while (true)
{
if (items.Count == 0)
Monitor.Wait(waiting);
object real = null;
lock(items) {
object item = items.Dequeue();
real = item;
}
if(real == null)
continue;
.. bla bla bla
}
}
2nd Thread involves
public void AddItem(object o)
{
... bla bla bla
lock(items)
{
items.Enqueue(o);
}
Monitor.PulseAll(waiting);
}
If you have access to .NET 4.0, what you want to do can be achieved by BlockingCollection<T>.
If you want to do it yourself by means of the
Monitorclass and signaling withPulse(), you are actually on the right track.You get the exception because to call
Wait(),Pulse()andPulseAll(), you have to own thelockon the specified object. You happen to miss this onwaiting.A sample basic thread-safe queue that can be used:
foreachon the consumer,whileor your favorite conditional construct on the producer side,lock(),Monitor.Pulse(),Monitor.PulseAll()andMonitor.Wait():.
Sample usage: