wasSharp – Diff between revs 54 and 55
?pathlinks?
Rev 54 | Rev 55 | |||
---|---|---|---|---|
1 | // -------------------------------------------------------------------------------------------------------------------- |
- | ||
2 | // <copyright file="ObservableConcurrentQueue.cs" company="BledSoft"> |
- | ||
3 | // This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. |
- | ||
4 | // To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/. |
- | ||
5 | // </copyright> |
- | ||
6 | // <Author> |
- | ||
7 | // Cheikh Younes |
1 | using System; |
|
8 | // </Author> |
- | ||
9 | // -------------------------------------------------------------------------------------------------------------------- |
- | ||
10 | using System.Collections.Concurrent; |
2 | using System.Threading; |
|
11 | using System.Threading.Tasks; |
3 | using System.Threading.Tasks; |
|
- | 4 | using System.Collections.ObjectModel; |
||
- | 5 | using System.Collections.Concurrent; |
||
- | 6 | using System.Collections; |
||
- | 7 | using System.Collections.Generic; |
||
- | 8 | using System.Collections.Specialized; |
||
- | 9 | using System.Linq; |
||
12 | |
10 | |
|
13 | namespace wasSharp.Collections.Specialized |
11 | namespace wasSharp.Collections.Specialized |
|
14 | { |
12 | { |
|
15 | /// <summary> |
13 | /// <summary> |
|
16 | /// The observable concurrent queue. |
14 | /// The observable concurrent queue. |
|
17 | /// </summary> |
15 | /// </summary> |
|
18 | /// <typeparam name="T"> |
16 | /// <typeparam name="T"> |
|
19 | /// The content type |
17 | /// The content type |
|
20 | /// </typeparam> |
18 | /// </typeparam> |
|
21 | public sealed class ObservableConcurrentQueue<T> : ConcurrentQueue<T> |
19 | public sealed class ObservableConcurrentQueue<T> : ConcurrentQueue<T>, INotifyCollectionChanged |
|
22 | { |
20 | { |
|
23 | #region Public Events |
21 | public event NotifyCollectionChangedEventHandler CollectionChanged; |
|
24 | |
- | ||
25 | /// <summary> |
- | ||
26 | /// Occurs when concurrent queue elements [changed]. |
- | ||
27 | /// </summary> |
- | ||
28 | public event ConcurrentQueueChangedEventHandler<T> ContentChanged; |
- | ||
29 | |
- | ||
30 | #endregion |
- | ||
31 | |
- | ||
32 | #region Public Methods and Operators |
- | ||
33 | |
- | ||
34 | /// <summary> |
- | ||
35 | /// Adds an object to the end of the <see cref="T:System.Collections.Concurrent.ConcurrentQueue`1"/>. |
- | ||
36 | /// </summary> |
- | ||
37 | /// <param name="item"> |
- | ||
38 | /// The object to add to the end of the <see cref="T:System.Collections.Concurrent.ConcurrentQueue`1"/> |
- | ||
39 | /// . The value can be a null reference (Nothing in Visual Basic) for reference types. |
- | ||
40 | /// </param> |
22 | |
|
41 | public new async Task Enqueue(T item) |
23 | private new void Enqueue(T item) |
|
42 | { |
24 | { |
|
- | 25 | EnqueueAsync(item).RunSynchronously(); |
||
- | 26 | } |
||
- | 27 | |
||
43 | await new Task(() => |
28 | public async Task EnqueueAsync(T item) => await Task.Run(() => |
|
44 | { |
29 | { |
|
45 | base.Enqueue(item); |
30 | base.Enqueue(item); |
|
46 | |
- | ||
47 | // Raise event added event |
31 | |
|
48 | this.OnContentChanged( |
32 | OnCollectionChanged( |
|
49 | new NotifyConcurrentQueueChangedEventArgs<T>(NotifyConcurrentQueueChangedAction.Enqueue, item)); |
33 | new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item)); |
|
50 | }); |
- | ||
51 | } |
- | ||
52 | |
- | ||
53 | /// <summary> |
- | ||
54 | /// Attempts to remove and return the object at the beginning of the |
- | ||
55 | /// <see cref="T:System.Collections.Concurrent.ConcurrentQueue`1"/>. |
- | ||
56 | /// </summary> |
- | ||
57 | /// <param name="result"> |
- | ||
58 | /// When this method returns, if the operation was successful, <paramref name="result"/> contains the |
- | ||
59 | /// object removed. If no object was available to be removed, the value is unspecified. |
- | ||
60 | /// </param> |
- | ||
61 | /// <returns> |
- | ||
62 | /// true if an element was removed and returned from the beginning of the |
- | ||
63 | /// <see cref="T:System.Collections.Concurrent.ConcurrentQueue`1"/> successfully; otherwise, false. |
34 | }); |
|
64 | /// </returns> |
35 | |
|
65 | public new bool TryDequeue(out T result) |
36 | private new bool TryDequeue(out T result) |
|
66 | { |
37 | { |
|
67 | if (!base.TryDequeue(out result)) |
38 | result = DequeueAsync().Result; |
|
68 | { |
- | ||
69 | return false; |
39 | if (result.Equals(default(T))) |
|
70 | } |
40 | return false; |
|
71 | |
- | ||
72 | // Raise item dequeued event |
41 | |
|
73 | this.OnContentChanged( |
42 | return true; |
|
74 | new NotifyConcurrentQueueChangedEventArgs<T>(NotifyConcurrentQueueChangedAction.Dequeue, result)); |
43 | } |
|
75 | |
44 | |
|
76 | if (this.IsEmpty) |
- | ||
77 | { |
- | ||
- | 45 | public async Task<T> DequeueAsync() => await Task.Run(() => |
||
- | 46 | { |
||
- | 47 | if (!base.TryDequeue(out T item)) |
||
78 | // Raise Queue empty event |
48 | return default(T); |
|
79 | this.OnContentChanged( |
49 | |
|
80 | new NotifyConcurrentQueueChangedEventArgs<T>(NotifyConcurrentQueueChangedAction.Empty)); |
- | ||
81 | } |
- | ||
82 | |
- | ||
83 | return true; |
- | ||
84 | } |
- | ||
85 | |
- | ||
86 | /// <summary> |
- | ||
87 | /// Attempts to return an object from the beginning of the |
- | ||
88 | /// <see cref="T:System.Collections.Concurrent.ConcurrentQueue`1"/> without removing it. |
- | ||
89 | /// </summary> |
- | ||
90 | /// <param name="result"> |
- | ||
91 | /// When this method returns, <paramref name="result"/> contains an object from the beginning of the |
50 | OnCollectionChanged( |
|
92 | /// <see cref="T:System.Collections.Concurrent.ConcurrentQueue`1"/> or an unspecified value if the operation failed. |
51 | new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item)); |
|
93 | /// </param> |
52 | |
|
94 | /// <returns> |
53 | return item; |
|
95 | /// true if and object was returned successfully; otherwise, false. |
- | ||
96 | /// </returns> |
- | ||
97 | public new bool TryPeek(out T result) |
- | ||
98 | { |
- | ||
99 | var retValue = base.TryPeek(out result); |
- | ||
100 | if (retValue) |
54 | }); |
|
101 | { |
55 | |
|
- | 56 | public async Task<T> PeekAsync() => await Task.Run(() => |
||
102 | // Raise item dequeued event |
57 | { |
|
- | 58 | if (!base.TryPeek(out T item)) |
||
- | 59 | return default(T); |
||
103 | this.OnContentChanged( |
60 | |
|
104 | new NotifyConcurrentQueueChangedEventArgs<T>(NotifyConcurrentQueueChangedAction.Peek, result)); |
- | ||
105 | } |
- | ||
106 | |
61 | return item; |
|
107 | return retValue; |
- | ||
108 | } |
- | ||
109 | |
62 | }); |
|
- | 63 | |
||
110 | #endregion |
64 | private new bool TryPeek(out T result) |
|
111 | |
65 | { |
|
112 | #region Methods |
- | ||
113 | |
- | ||
114 | /// <summary> |
- | ||
115 | /// Raises the <see cref="E:Changed"/> event. |
66 | result = PeekAsync().Result; |
|
116 | /// </summary> |
- | ||
117 | /// <param name="args"> |
67 | |
|
- | 68 | if (result.Equals(default(T))) |
||
- | 69 | return false; |
||
- | 70 | |
||
- | 71 | return true; |
||
- | 72 | } |
||
118 | /// The <see cref="NotifyConcurrentQueueChangedEventArgs{T}"/> instance containing the event data. |
73 | |
|
119 | /// </param> |
74 | private void OnCollectionChanged(NotifyCollectionChangedEventArgs args) |
|
120 | private void OnContentChanged(NotifyConcurrentQueueChangedEventArgs<T> args) |
75 | { |
|
121 | { |
76 | CollectionChanged?.Invoke(this, args); |
|
122 | var handler = this.ContentChanged; |
77 | } |
|
123 | if (handler != null) |
78 | |
|
124 | { |
79 | |
|
125 | handler(this, args); |
80 | public async Task Clear() |
|
126 | } |
81 | { |
|
127 | } |
82 | while (!base.IsEmpty) |
|
128 | |
83 | await DequeueAsync(); |
|
129 | #endregion |
84 | } |
|
130 | } |
85 | } |
|
131 | } |
86 | } |
|
132 | |
87 | |
|
133 |
|
88 |
|
|
134 | |
89 | |
|
135 | |
90 | |
|
136 | |
91 | |