Работаю с задачей организации очереди поставщик-потребитель , в роли потребителя выступает отдельный поток. Собственно рабочий код ниже
| Код |
using System.Threading;
namespace multySteam { class Program { class ProducerConsumerQueue : IDisposable { EventWaitHandle wh = new AutoResetEvent(false);
Thread worker;
object locker = new object(); Queue<string> tasks = new Queue<string>(); public ProducerConsumerQueue() { worker = new Thread(Work); worker.Name = "worker 1"; worker.Start();
} public void EnqueueTask(string task) { lock (locker) tasks.Enqueue(task);
wh.Set(); } public void Dispose() { EnqueueTask(null); // Сигнал Потребителю на завершение worker.Join(); // Ожидание завершения Потребителя wh.Close(); // Освобождение ресурсов
} void Work() { while (true) { string task = null;
lock (locker) { if (tasks.Count > 0) { task = tasks.Dequeue(); if (task == null) return; } }
if (task != null) { Console.WriteLine("Выполняется задача: " + task); Thread.Sleep(1000); // симуляция работы...
} else wh.WaitOne(); // Больше задач нет, ждем сигнала... } } }
class Test { static int j= 0;
static void Main() { System.Timers.Timer T = new System.Timers.Timer(1000); T.Elapsed += new System.Timers.ElapsedEventHandler(T_Elapsed);
T.Start();
using(ProducerConsumerQueue q = new ProducerConsumerQueue()) {
q.EnqueueTask("Привет!");
for (int i = 0; i < 150; i++) q.EnqueueTask("Сообщение " + i);
q.EnqueueTask("Пока!"); }
T.Stop(); Console.WriteLine("Заняло "+ j.ToString()); Console.ReadKey();
// Выход из using приводит к вызову Dispose, который ставит // в очередь null-задачу и ожидает, пока Потребитель не завершится. }
static void T_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { j++; if (j % 10 == 0) { Console.WriteLine("_"+j.ToString()+"_"); } }
}
|
Проблемы возникают при попытке увеличить количество потоков запрашивающих очередь ,модифицируя метод ProducerConsumerQueue :
| Код | public ProducerConsumerQueue() { for (int i = 0; i < 5; i++) { worker = new Thread(Work); worker.Name = "worker 1"; worker.Start();
} }
|
После отработки всей очереди не проходит Dispose и таймер продолжает тикать. Заранее спасибо за все возможные тычки моей мордой в недоработки и рекомендованные изменения.
p.s. FAQ страничка http://base.vingrad.ru/NET-996 лежит |