namespace System.Collections { using System.Threading; /// /// Same as Queue except Dequeue function blocks until there is an object to return. /// Note: This class does not need to be synchronized /// public class BlockingQueue : Queue { private bool open; /// /// Create new BlockingQueue. /// /// The System.Collections.ICollection to copy elements from public BlockingQueue(ICollection col) : base(col) { open = true; } /// /// Create new BlockingQueue. /// /// The initial number of elements that the queue can contain /// The factor by which the capacity of the queue is expanded public BlockingQueue(int capacity, float growFactor) : base(capacity, growFactor) { open = true; } /// /// Create new BlockingQueue. /// /// The initial number of elements that the queue can contain public BlockingQueue(int capacity) : base(capacity) { open = true; } /// /// Create new BlockingQueue. /// public BlockingQueue() : base() { open = true; } /// /// BlockingQueue Destructor (Close queue, resume any waiting thread). /// ~BlockingQueue() { Close(); } /// /// Remove all objects from the Queue. /// public override void Clear() { lock (base.SyncRoot) { base.Clear(); } } /// /// Remove all objects from the Queue, resume all dequeue threads. /// public void Close() { lock (base.SyncRoot) { open = false; base.Clear(); Monitor.PulseAll(base.SyncRoot); // resume any waiting threads } } /// /// Removes and returns the object at the beginning of the Queue. /// /// Object in queue. public override object Dequeue() { return Dequeue(Timeout.Infinite); } /// /// Removes and returns the object at the beginning of the Queue. /// /// time to wait before returning /// Object in queue. public object Dequeue(TimeSpan timeout) { return Dequeue(timeout.Milliseconds); } /// /// Removes and returns the object at the beginning of the Queue. /// /// time to wait before returning (in milliseconds) /// Object in queue. public object Dequeue(int timeout) { lock (base.SyncRoot) { while (open && (base.Count == 0)) { if (!Monitor.Wait(base.SyncRoot, timeout)) throw new InvalidOperationException("Timeout"); } if (open) return base.Dequeue(); else throw new InvalidOperationException("Queue Closed"); } } /// /// Adds an object to the end of the Queue. /// /// Object to put in queue public override void Enqueue(object obj) { lock (base.SyncRoot) { base.Enqueue(obj); Monitor.Pulse(base.SyncRoot); } } /// /// Open Queue. /// public void Open() { lock (base.SyncRoot) { open = true; } } /// /// Gets flag indicating if queue has been closed. /// public bool Closed { get { return !open; } } } }