using System;
using System.Collections.Generic;
using System.Threading;
namespace GMService {
class Program {
static void Main() {
ProducerConsumerQueue q = new ProducerConsumerQueue(20);
q.EnqueueTask("Hello");
Random r = new Random();
List<Thread> producers = new List<Thread>();
for (int i = 0; i < 100; i ++) {
Producer p = new Producer(q, i % 5 + r.Next(0, 5));
Thread t = new Thread(p.Produce);
producers.Add(t);
t.Start();
}
foreach (Thread thread in producers) {
thread.Join();
}
q.Exit();
Console.Read();
}
}
public class Producer {
public Producer(ProducerConsumerQueue queue, int pause) {
_queue = queue;
_pause = pause;
}
public void Produce() {
Thread.Sleep(_pause * 1000);
_queue.EnqueueTask("Producer " + Thread.CurrentThread.ManagedThreadId + " says hello.");
}
private readonly ProducerConsumerQueue _queue;
private readonly int _pause;
}
public class ProducerConsumerQueue {
AutoResetEvent handle = new AutoResetEvent(false);
List<Thread> workers = new List<Thread>();
object locker = new object();
Queue<string> tasks = new Queue<string>();
private readonly int _maxWorkerNumber;
public ProducerConsumerQueue(int maxWorkers) {
_maxWorkerNumber = Math.Max(1, maxWorkers);
for (int i = 0; i < _maxWorkerNumber; i ++) {
Thread worker = new Thread(Work);
workers.Add(worker);
worker.Start();
}
}
public void Exit() {
EnqueueTask(null);
foreach (Thread thread in workers) {
thread.Join();
}
handle.Close();
}
private void Work() {
while (true) {
string task = null;
lock (locker) {
if (tasks.Count > 0) {
if (tasks.Peek() == null) {
handle.Set();
return;
}
task = tasks.Dequeue();
}
}
if (task != null) {
Console.WriteLine("Performing task:" + task);
Thread.Sleep(500);
} else {
handle.WaitOne();
}
}
}
public void EnqueueTask(string task) {
lock (locker) {
tasks.Enqueue(task);
handle.Set();
}
}
}
}