using System; using System.Collections; using System.Threading; namespace CodeGuru.MultithreadedPart2 { /// /// Example console application demonstrating the use of a /// monitor. /// class MonitorExample { // Constant representing the maximum number of items to enqueue const int MAX_QUEUE_SIZE = 10; // Queue to hold items Queue _queue; /// /// Constructor /// public MonitorExample() { this._queue = new Queue(); } /// /// The main entry point for the application. /// [STAThread] static void Main(string[] args) { // Start two threads to add and remove queue items MonitorExample test = new MonitorExample(); Thread enqueueThread = new Thread(new ThreadStart(test.Enqueue)); Thread dequeueThread = new Thread(new ThreadStart(test.Dequeue)); enqueueThread.Start(); dequeueThread.Start(); // Wait to the end of the two threads then print the number of // queue elements enqueueThread.Join(); dequeueThread.Join(); } /// /// Add items to the queue. /// public void Enqueue() { int counter = 0; Monitor.Enter(this._queue); while( counter < MAX_QUEUE_SIZE ) { // Wait while the queue is busy Monitor.Wait(this._queue); // Add one item to the queue Console.WriteLine("Adding item {0} to queue", counter.ToString()); this._queue.Enqueue(counter++); // Release the queue Monitor.Pulse(this._queue); } Monitor.Exit(this._queue); } /// /// Remove items from the queue. /// public void Dequeue() { Monitor.Enter(this._queue); // Release the queue because we just locked it // setting up the region lock Monitor.Pulse(this._queue); // Wait while the queue is busy // and exit on the timeout when the first thread stopped while(Monitor.Wait(this._queue, 500)) { // Remove the first item and display it int counter = (int)this._queue.Dequeue(); Console.WriteLine("Removed item {0} from queue", counter.ToString()); // Release the queue Monitor.Pulse(this._queue); } Monitor.Exit(this._queue); } } }