Hi Pete
This morning I changed some code. I previously had a Queue<IFileProcessor>
which I checked in a thread and called Execute() on each instance as I
removed it. I changed this into a simple class which has a SyncRoot which I
can Wait and Pulse, and then some code to process the queue.
Now I have 3 queues
Dictionary<EstimatedProcessTime, Queue<IFileProcessor>> Queues;
Previously I did something like this
while (true)
{
bool hasWork;
//These take milliseconds, so we do all of these first
Dequeue(Queues[EstimatedProcessTime.Immediate], out hasWork);
if (hasWork)
continue;
//These take about 1 second, so do these when the Immediate ones are
done
Dequeue(Queues[EstimatedProcessTime.Medium], out hasWork);
if (hasWork)
continue;
//These take about 12 seconds, so only do when then others are done
Dequeue(Queues[EstimatedProcessTime.Long], out hasWork);
Thread.Sleep(1000);
}
private void Dequeue(Queue<IFileProcessor> queue, out bool hasWork)
{
IFileProcessor processor = null;
lock(queue)
{
if (queue.Count > 0)
processor = queue.Dequeue();
hasWork = (queue.Count > 0);
}
processor.Execute();
}
The problem with this is that the 12 second process would stop the
immediate/medium length processes from executing. I have intended to make
this 1 thread per queue for a few days now, so after our discussion I
changed it this morning...
public class FileProcessorQueue
{
public readonly object SyncRoot;
readonly Thread Thread;
readonly Queue<IFileProcessor> Queue;
public FileProcessorQueue()
{
SyncRoot = new object();
Queue = new Queue<IFileProcessor>();
Thread = new Thread(new ThreadStart(ProcessQueue));
Thread.Start();
}
public void Enqueue(IFileProcessor processor)
{
lock (SyncRoot)
{
Queue.Enqueue(processor);
Monitor.Pulse(SyncRoot);
}
}
private void ProcessQueue()
{
while (true)
{
IFileProcessor processor = null;
lock (SyncRoot)
{
if (Queue.Count > 0)
processor = Queue.Dequeue();
else
Monitor.Wait(SyncRoot);
}//lock syncroot
if (processor != null)
{
processor.Execute();
if (processor.State == FileProcessState.Ready)
Enqueue(processor);
}
}//while true
}
public void Clear()
{
lock (SyncRoot)
{
Queue.Clear();
}
}
}
Much happier now
