wasSharp

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 53  →  ?path2? @ 54
/Collections/Specialized/ObservableConcurrentQueue.cs
@@ -0,0 +1,131 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ObservableConcurrentQueue.cs" company="BledSoft">
// This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
// To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/.
// </copyright>
// <Author>
// Cheikh Younes
// </Author>
// --------------------------------------------------------------------------------------------------------------------
using System.Collections.Concurrent;
using System.Threading.Tasks;
 
namespace wasSharp.Collections.Specialized
{
/// <summary>
/// The observable concurrent queue.
/// </summary>
/// <typeparam name="T">
/// The content type
/// </typeparam>
public sealed class ObservableConcurrentQueue<T> : ConcurrentQueue<T>
{
#region Public Events
 
/// <summary>
/// Occurs when concurrent queue elements [changed].
/// </summary>
public event ConcurrentQueueChangedEventHandler<T> ContentChanged;
 
#endregion
 
#region Public Methods and Operators
 
/// <summary>
/// Adds an object to the end of the <see cref="T:System.Collections.Concurrent.ConcurrentQueue`1"/>.
/// </summary>
/// <param name="item">
/// The object to add to the end of the <see cref="T:System.Collections.Concurrent.ConcurrentQueue`1"/>
/// . The value can be a null reference (Nothing in Visual Basic) for reference types.
/// </param>
public new async Task Enqueue(T item)
{
await new Task(() =>
{
base.Enqueue(item);
 
// Raise event added event
this.OnContentChanged(
new NotifyConcurrentQueueChangedEventArgs<T>(NotifyConcurrentQueueChangedAction.Enqueue, item));
});
}
 
/// <summary>
/// Attempts to remove and return the object at the beginning of the
/// <see cref="T:System.Collections.Concurrent.ConcurrentQueue`1"/>.
/// </summary>
/// <param name="result">
/// When this method returns, if the operation was successful, <paramref name="result"/> contains the
/// object removed. If no object was available to be removed, the value is unspecified.
/// </param>
/// <returns>
/// true if an element was removed and returned from the beginning of the
/// <see cref="T:System.Collections.Concurrent.ConcurrentQueue`1"/> successfully; otherwise, false.
/// </returns>
public new bool TryDequeue(out T result)
{
if (!base.TryDequeue(out result))
{
return false;
}
 
// Raise item dequeued event
this.OnContentChanged(
new NotifyConcurrentQueueChangedEventArgs<T>(NotifyConcurrentQueueChangedAction.Dequeue, result));
 
if (this.IsEmpty)
{
// Raise Queue empty event
this.OnContentChanged(
new NotifyConcurrentQueueChangedEventArgs<T>(NotifyConcurrentQueueChangedAction.Empty));
}
 
return true;
}
 
/// <summary>
/// Attempts to return an object from the beginning of the
/// <see cref="T:System.Collections.Concurrent.ConcurrentQueue`1"/> without removing it.
/// </summary>
/// <param name="result">
/// When this method returns, <paramref name="result"/> contains an object from the beginning of the
/// <see cref="T:System.Collections.Concurrent.ConcurrentQueue`1"/> or an unspecified value if the operation failed.
/// </param>
/// <returns>
/// true if and object was returned successfully; otherwise, false.
/// </returns>
public new bool TryPeek(out T result)
{
var retValue = base.TryPeek(out result);
if (retValue)
{
// Raise item dequeued event
this.OnContentChanged(
new NotifyConcurrentQueueChangedEventArgs<T>(NotifyConcurrentQueueChangedAction.Peek, result));
}
 
return retValue;
}
 
#endregion
 
#region Methods
 
/// <summary>
/// Raises the <see cref="E:Changed"/> event.
/// </summary>
/// <param name="args">
/// The <see cref="NotifyConcurrentQueueChangedEventArgs{T}"/> instance containing the event data.
/// </param>
private void OnContentChanged(NotifyConcurrentQueueChangedEventArgs<T> args)
{
var handler = this.ContentChanged;
if (handler != null)
{
handler(this, args);
}
}
 
#endregion
}
}