I am trying to create a system that processes a queue of work. The system has the following specifications:
I don't know how long your tasks will be running, but it seems that the best thing to do would be to use ThreadPool. Furthermore, I would use, and actually have used, only one central queue - that alone will remove some complexity. I have one Thread that handles the queue and does an action on the item in your case it would be to queue a task.
As for making the queue threadsafe, there is a ConcurrentQueue in System.Collections.Concurrent for that very purpose (msdn, benchmark vs locking queue).
Now, throw in a BlockingCollection (msdn) and you have all you need.
BlockingCollection sendQueue = new BlockingCollection(new ConcurrentQueue());
while (true)
{
var packet = sendQueue.Take(); //this blocks if there are no items in the queue.
ThreadPool.QueueUserWorkItem(state =>
{
var data = (Packet)state;
//do whatever you have to do
}, packet );
}
and somewhere there is something that sendQueue.Add(packet);
To sum up,
I think that's it.
ps: if you have to control the amount of threads, use "Smart Thread Pool" as suggested by josh3736