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);
}
}
}