/Collections/Specialized/NotifyConcurrentQueueChangedEventArgs.cs |
@@ -0,0 +1,72 @@ |
// -------------------------------------------------------------------------------------------------------------------- |
// <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; |
|
namespace wasSharp.Collections.Specialized |
{ |
/// <summary> |
/// The notify concurrent queue changed event args. |
/// </summary> |
/// <typeparam name="T"> |
/// The item type |
/// </typeparam> |
public class NotifyConcurrentQueueChangedEventArgs<T> : EventArgs |
{ |
#region Constructors and Destructors |
|
/// <summary> |
/// Initializes a new instance of the <see cref="NotifyConcurrentQueueChangedEventArgs{T}"/> class. |
/// </summary> |
/// <param name="action"> |
/// The action. |
/// </param> |
/// <param name="changedItem"> |
/// The changed item. |
/// </param> |
public NotifyConcurrentQueueChangedEventArgs(NotifyConcurrentQueueChangedAction action, T changedItem) |
{ |
this.Action = action; |
this.ChangedItem = changedItem; |
} |
|
/// <summary> |
/// Initializes a new instance of the <see cref="NotifyConcurrentQueueChangedEventArgs{T}"/> class. |
/// </summary> |
/// <param name="action"> |
/// The action. |
/// </param> |
public NotifyConcurrentQueueChangedEventArgs(NotifyConcurrentQueueChangedAction action) |
{ |
this.Action = action; |
} |
|
#endregion |
|
#region Public Properties |
|
/// <summary> |
/// Gets the action. |
/// </summary> |
/// <value> |
/// The action. |
/// </value> |
public NotifyConcurrentQueueChangedAction Action { get; private set; } |
|
/// <summary> |
/// Gets the changed item. |
/// </summary> |
/// <value> |
/// The changed item. |
/// </value> |
public T ChangedItem { get; private set; } |
|
#endregion |
} |
} |
/Collections/Specialized/ObservableConcurrentQueue.cs |
@@ -1,12 +1,14 @@ |
using System; |
using System.Threading; |
// -------------------------------------------------------------------------------------------------------------------- |
// <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; |
using System.Collections.ObjectModel; |
using System.Collections.Concurrent; |
using System.Collections; |
using System.Collections.Generic; |
using System.Collections.Specialized; |
using System.Linq; |
|
namespace wasSharp.Collections.Specialized |
{ |
@@ -16,71 +18,114 @@ |
/// <typeparam name="T"> |
/// The content type |
/// </typeparam> |
public sealed class ObservableConcurrentQueue<T> : ConcurrentQueue<T>, INotifyCollectionChanged |
public sealed class ObservableConcurrentQueue<T> : ConcurrentQueue<T> |
{ |
public event NotifyCollectionChangedEventHandler CollectionChanged; |
#region Public Events |
|
private new void Enqueue(T item) |
/// <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) |
{ |
EnqueueAsync(item).RunSynchronously(); |
} |
|
public async Task EnqueueAsync(T item) => await Task.Run(() => |
await new Task(() => |
{ |
base.Enqueue(item); |
|
OnCollectionChanged( |
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item)); |
// Raise event added event |
this.OnContentChanged( |
new NotifyConcurrentQueueChangedEventArgs<T>(NotifyConcurrentQueueChangedAction.Enqueue, item)); |
}); |
} |
|
private new bool TryDequeue(out T result) |
/// <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) |
{ |
result = DequeueAsync().Result; |
if (result.Equals(default(T))) |
if (!base.TryDequeue(out result)) |
{ |
return false; |
} |
|
return true; |
} |
// Raise item dequeued event |
this.OnContentChanged( |
new NotifyConcurrentQueueChangedEventArgs<T>(NotifyConcurrentQueueChangedAction.Dequeue, result)); |
|
public async Task<T> DequeueAsync() => await Task.Run(() => |
if (this.IsEmpty) |
{ |
if (!base.TryDequeue(out T item)) |
return default(T); |
// Raise Queue empty event |
this.OnContentChanged( |
new NotifyConcurrentQueueChangedEventArgs<T>(NotifyConcurrentQueueChangedAction.Empty)); |
} |
|
OnCollectionChanged( |
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item)); |
return true; |
} |
|
return item; |
}); |
|
public async Task<T> PeekAsync() => await Task.Run(() => |
/// <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) |
{ |
if (!base.TryPeek(out T item)) |
return default(T); |
var retValue = base.TryPeek(out result); |
if (retValue) |
{ |
// Raise item dequeued event |
this.OnContentChanged( |
new NotifyConcurrentQueueChangedEventArgs<T>(NotifyConcurrentQueueChangedAction.Peek, result)); |
} |
|
return item; |
}); |
return retValue; |
} |
|
private new bool TryPeek(out T result) |
{ |
result = PeekAsync().Result; |
#endregion |
|
if (result.Equals(default(T))) |
return false; |
#region Methods |
|
return true; |
} |
|
private void OnCollectionChanged(NotifyCollectionChangedEventArgs args) |
/// <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) |
{ |
CollectionChanged?.Invoke(this, args); |
var handler = this.ContentChanged; |
if (handler != null) |
{ |
handler(this, args); |
} |
} |
|
|
public async Task Clear() |
{ |
while (!base.IsEmpty) |
await DequeueAsync(); |
} |
#endregion |
} |
} |