Re: thread communication

Tech-Archive recommends: Speed Up your PC by fixing your registry



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 :-)



--
Pete
====
http://mrpmorris.blogspot.com
http://www.capableobjects.com

.



Relevant Pages

  • Re: What does Queue.Synchronized() return
    ... Here is example how syncronized queue is implemented. ... sync wrapper should work on any queue that derives from Queue. ... You need to lock SyncRoot ... locks the SyncWrapper does (one for Count "Get" and one for the Dequeue ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: How to improve performance of Queue accessing between 2 thread
    ... /// A blocking queue derived from Queue. ... public class BlockingQueue: Queue ... private readonly object syncRoot = new object; ... lock ...
    (microsoft.public.dotnet.framework)
  • Re: How to improve performance of Queue accessing between 2 thread
    ... /// A blocking queue derived from Queue. ... public class BlockingQueue: Queue ... private readonly object syncRoot = new object; ... lock ...
    (microsoft.public.dotnet.framework)
  • Re: Threading/Locking
    ... Thats what I ended up doing putting the data into a Queue and then creating ... "Alan Pretre" wrote: ... > and retrieving on the queue through its SyncRoot member. ...
    (microsoft.public.dotnet.languages.csharp)