// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved. using System; using System.Collections; using System.Collections.Generic; using System.Threading; namespace Tools.DotNETCommon.ThreadSafeQueue { /// /// A thread-safe reader-writer-locked wrapper to the stock .NET Queue container. /// /// The type of the classes that will be queued in this container. /// All operations are exception checked, so it will return default values rather than crash when used improperly. public class ThreadSafeQueue { /// The key to protecting the contained queue properly private ReaderWriterLock AccessLock = new ReaderWriterLock(); /// The protected queue private Queue ProtectedQueue = new Queue(); /// /// Default constructor. /// public ThreadSafeQueue() { } /// /// Completely empties the queue. /// public void Clear() { // Modifies the collection, use a writer lock AccessLock.AcquireWriterLock( Timeout.Infinite ); try { ProtectedQueue.Clear(); } finally { AccessLock.ReleaseWriterLock(); } } /// /// Queue up a new element. /// /// A new element to queue. public void Enqueue( TValue V ) { // Modifies the collection, use a writer lock AccessLock.AcquireWriterLock( Timeout.Infinite ); try { ProtectedQueue.Enqueue( V ); } finally { AccessLock.ReleaseWriterLock(); } } /// /// Dequeue an existing element. /// /// A previously queued element. public TValue Dequeue() { // Modifies the collection, use a writer lock AccessLock.AcquireWriterLock( Timeout.Infinite ); TValue V = default( TValue ); try { V = ProtectedQueue.Dequeue(); } finally { AccessLock.ReleaseWriterLock(); } return V; } /// /// Return all elements of the queue as an array. /// /// An array of all elements in the queue. public TValue[] ToArray() { // Does not modify the collection, use a reader lock AccessLock.AcquireReaderLock( Timeout.Infinite ); TValue[] ReturnValues; try { ReturnValues = ProtectedQueue.ToArray(); } finally { AccessLock.ReleaseReaderLock(); } return ReturnValues; } /// /// Return the number of elements in the queue. /// /// A count of elements in the queue. public int Count { get { // Does not modify the collection, use a reader lock AccessLock.AcquireReaderLock( Timeout.Infinite ); int ReturnValue = 0; try { ReturnValue = ProtectedQueue.Count; } finally { AccessLock.ReleaseReaderLock(); } return ReturnValue; } } } }