Following explanation is from msdn document
The Monitor class does not maintain state indicating that the Pulse
method has been called. Thus, if you call Pulse when no threads are
waiting, the next thread that calls Wait blocks as if Pulse had never
been called.
If not threads is wating then pluse is ignored??
I have following code ...it starts 3 threads and enques 12 tasks
before even 3 threads finished work that means for next 9 pulses there
are not threads waiting. Still all the tasks get processed. According
to documentatiion next 9 pulses should be ignored as if they never
happened. Did I misunderstood the documentation.
using System;
using System.Threading;
using System.Collections.Generic;
namespace ThreadingConsole
{
public class TaskQueue : IDisposable
{
object locker = new object();
Thread[] workers;
public Queue<string> taskQ = new Queue<string>();
public TaskQueue(int workerCount)
{
workers = new Thread[workerCount];
// Create and start a separate thread for each worker
for (int i = 0; i < workerCount; i++)
(workers[i] = new Thread(Consume)).Start();
}
public void Dispose()
{
// Enqueue one null task per worker to make each exit.
foreach (Thread worker in workers) EnqueueTask(null);
}
public void EnqueueTask(string task)
{
lock (locker)
{
taskQ.Enqueue(task); // We must pulse
because we're
Console.WriteLine("START : " + task + " " +
DateTime.Now.ToString()); // Perform task.
Monitor.Pulse(locker); // changing a blocking
condition.
}
}
void Consume()
{
while (true) // Keep consuming
until
{ // told otherwise
string task;
lock (locker)
{
while (taskQ.Count == 0) Monitor.Wait(locker);
task = taskQ.Dequeue();
}
if (task == null) return; // This signals our
exit
Thread.Sleep(10000); // Simulate time-
consuming task
Console.WriteLine("END : " + task + " "
+DateTime.Now.ToString()); // Perform task.
}
}
public void Start()
{
string[] sTasks = GetNewWork();
Console.WriteLine("Start Enquing Tasks : " +
DateTime.Now.ToString());
foreach (string s in sTasks)
this.EnqueueTask(s);
Console.WriteLine("Finished Enquing Tasks : " +
DateTime.Now.ToString());
}
string[] GetNewWork()
{
return new string[] { "AAAAA", "BBBBB", "CCCCC", "DDDD",
"AAAAA1", "BBBBB1", "CCCCC1", "DDDD1", "AAAAA2", "BBBBB2", "CCCCC2",
"DDDD2", "AAAAA3", "BBBBB3", "CCCCC3", "DDDD3" };
}
}
}
class Program
{
static void Main(string[] args)
{
using (TaskQueue queue = new TaskQueue(3))
{
queue.Start();
Console.ReadLine();
}
}
}