I have a problem that I can't figure out. It might not be easy to explain.
I have a singleton class with this private constructor:
private BarcodeMonitor()
{
processors[Machines.H1] = new BarcodeProcessor { Queue = new BlockingQueue<BarcodeData>("H1") };
processors[Machines.H2] = new BarcodeProcessor { Queue = new BlockingQueue<BarcodeData>("H2") };
processors[Machines.M] = new BarcodeProcessor { Queue = new BlockingQueue<BarcodeData>("M") };
processors[Machines.HP] = new BarcodeProcessor { Queue = new BlockingQueue<BarcodeData>("HP") };
foreach (KeyValuePair<Machines, BarcodeProcessor> pair in processors)
{
Thread t = new Thread(t1 => pair.Value.StartProccesingQueue());
t.Name = pair.Key.ToString() + "Processor";
t.Start();
threads.Add(t);
}
}
A new and unique BlockingQueue
is given to the BarcodeProcessor
and takes a name.
The BarcodeMonitor
has this method:
public BlockingQueue<BarcodeData> GetQueue(Machines machine)
{
var processor = processors[machine];
return processor.Queue;
}
so that incoming barcodes are put in the queue of the right machine. This works fine.
The barcodes are dequeued in StartProccesingQueue()
(of which 4 instances are running). In the dequeue method, I have:
System.Console.WriteLine(string.Format("Thread {0} is taking from queue {1}", Thread.CurrentThread.Name, name));
Dequeue()
uses Monitor.Wait(_internalQueue)
when the queue is empty. The Enqueue()
uses Monitor.PulseAll(_internalQueue)
to continue the waiting dequeue.
What is happening, is that the StartProccesingQueue()
method takes from other queues, even though it just access that Queue
property that is assigned with a new BlockingQueue
. In fact, thus far, I've only seen items from queue "M" being taken, and only the H1 and H2 threads are doing it.
I really don't get why this is happening.