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