Please note that the T object must implement
IEquatable!!
/// <summary>
/// Time Delay Queue.
/// Generic object must implement IEquatable.
/// </summary>
/// <typeparam name="T">Any generic type.</typeparam>
public class TimeDelayQueue<T> : IEnumerable<TimeDelay<T>>, INotifyCollectionChanged
{
/// <summary>
/// Base queue object.
/// </summary>
private Queue<TimeDelay<T>> queue;
/// <summary>
/// Creates a time delayed queue.
/// </summary>
public TimeDelayQueue()
{
//Initialize queue
queue = new Queue<TimeDelay<T>>();
}
/// <summary>
/// Removes and returns the object at the beginning of the System.Collections.Generic.Queue of T.
/// </summary>
/// <returns>Generic T</returns>
public T Dequeue()
{
//Output holder
T output = default(T);
//List of items that need to be requeued.
List<TimeDelay<T>> requeueList = new List<TimeDelay<T>>();
//While there is still item in the queue loop
while (queue.Count > 0)
{
//Get the item
TimeDelay<T> item = queue.Dequeue();
//Check for no release
if (item.Release == null)
{
output = item.Item;
break;
}
else
{
//Check to see if release date has passed
if (item.Release <= DateTime.Now)
{
output = item.Item;
break;
}
else
{
//Add to requeue list
requeueList.Add(item);
}
}
}
//Re-queue all items skipped for release date
foreach (TimeDelay<T> item in requeueList)
{
queue.Enqueue(item);
}
//If output has value then notify collection changed
if (output != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, new List<TimeDelay<T>>() { { new TimeDelay<T>(output, null) } }));
return output;
}
/// <summary>
/// Adds an object to the end of the System.Collections.Generic.Queue of T.
/// </summary>
/// <param name="item">Generic T</param>
public void Enqueue(T item)
{
TimeDelay<T> output = new TimeDelay<T>(item, null);
queue.Enqueue(output);
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, new List<TimeDelay<T>>() { output }));
}
/// <summary>
/// Adds an object to the end of the System.Collections.Generic.Queue of T.
/// </summary>
/// <param name="item">Generic T</param>
/// <param name="release">DateTime of release.</param>
public void Enqueue(T item, DateTime? release)
{
TimeDelay<T> output = new TimeDelay<T>(item, release);
queue.Enqueue(output);
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, new List<TimeDelay<T>>() { output }));
}
/// <summary>
/// Adds an object to the end of the System.Collections.Generic.Queue of T.
/// </summary>
/// <param name="item">Generic T</param>
/// <param name="waitMinutes">Minutes to wait before dequeue.</param>
public void Enqueue(T item, int waitMinutes)
{
TimeDelay<T> output = new TimeDelay<T>(item, DateTime.Now.AddMinutes(waitMinutes));
queue.Enqueue(output);
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, new List<TimeDelay<T>>() { output }));
}
/// <summary>
/// Creates a System.Collections.Generic.Queue of T from an System.Collections.Generic.IEnumereable of T
/// </summary>
/// <returns>List o TimeDelay of T objects.</returns>
public List<TimeDelay<T>> ToList()
{
return queue.ToList<TimeDelay<T>>();
}
/// <summary>
/// Removes all objects from System.Collections.Generic.Queue of T.
/// </summary>
public void Clear()
{
queue.Clear();
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
/// <summary>
/// Determines whether an element is in System.Collections.Generic.Queue of T.
/// </summary>
/// <param name="item">Generic T</param>
/// <returns>Flag indicating presence of item.</returns>
public bool Contains(TimeDelay<T> item)
{
return queue.Contains(item);
}
/// <summary>
/// Determines whether an element is in System.Collections.Generic.Queue of T.
/// </summary>
/// <param name="item">Generic T</param>
/// <returns>Flag indicating presence of item.</returns>
public bool Contains(T item)
{
return queue.Contains(new TimeDelay<T>(item, null));
}
/// <summary>
/// Gets the number of elements contained in the System.Collections.Generic.Queue of T.
/// </summary>
public int Count
{
get { return queue.Count; }
}
/// <summary>
/// Returns an enumerator that iterates through the System.Collections.Generic.Queue of T.
/// </summary>
/// <returns></returns>
public IEnumerator<TimeDelay<T>> GetEnumerator()
{
return queue.GetEnumerator();
}
/// <summary>
/// Returns an enumerator that iterates through the System.Collections.Generic.Queue of T.
/// </summary>
/// <returns></returns>
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return queue.GetEnumerator();
}
/// <summary>
/// Returns an enumerator that iterates through the System.Collections.Generic.Queue of T.
/// </summary>
/// <returns></returns>
IEnumerator<TimeDelay<T>> IEnumerable<TimeDelay<T>>.GetEnumerator()
{
return queue.GetEnumerator();
}
/// <summary>
/// CollectionChanged event.
/// </summary>
public event NotifyCollectionChangedEventHandler CollectionChanged;
}
/// <summary>
/// Time Delay.
/// </summary>
/// <typeparam name="T">Any generic type.</typeparam>
public class TimeDelay<T> : IEquatable<TimeDelay<T>>
{
/// <summary>
/// DateTime of release from queue.
/// </summary>
public DateTime? Release { get; protected set; }
/// <summary>
/// Generic item in the queue.
/// </summary>
public T Item { get; set; }
/// <summary>
/// Holder for
/// </summary>
/// <param name="item">Generic T</param>
/// <param name="release">DateTime of release.</param>
public TimeDelay(T item, DateTime? release)
{
//Store data
this.Item = item;
this.Release = release;
}
/// <summary>
/// Determines whether the specified TimeDelay object is equal to the current TimeDelay object.
/// </summary>
/// <param name="other"></param>
/// <returns></returns>
public bool Equals(TimeDelay<T> other)
{
return this.Item.Equals(other.Item);
}
}
Interesting code, but if it doesn't behave like a LIFO structure, can it really be a queue, strictly speaking ?
ReplyDeletePerhaps you should invent the 'Arr' structure !