2using System.Collections.Generic;
3using System.Threading.Tasks;
16 private readonly LinkedList<Item> queue =
new LinkedList<Item>();
17 private readonly LinkedList<TaskCompletionSource<T>> subscribers =
new LinkedList<TaskCompletionSource<T>>();
18 private readonly TaskCompletionSource<bool> terminatedTask =
new TaskCompletionSource<bool>();
19 private readonly
object synchObj =
new object();
20 private volatile int countItems = 0;
21 private volatile int countSubscribers = 0;
22 private bool disposed =
false;
23 private bool terminated =
false;
35 internal T Value {
get; }
36 internal TaskCompletionSource<bool> Processed =
new TaskCompletionSource<bool>();
38 internal Item(T Value)
53 return this.countItems;
67 return this.countSubscribers;
77 public Task<bool>
Add(T Item)
79 return this.
Add(Item,
false);
89 return this.
Add(Item,
false);
99 return this.
Add(Item,
true);
108 public Task<bool>
Add(T Item,
bool First)
112 if (this.terminated || this.disposed)
113 throw new ObjectDisposedException(
"Queue has been terminated.");
115 if (this.subscribers.First is
null)
117 Item Record =
new Item(Item);
120 this.queue.AddFirst(Record);
122 this.queue.AddLast(Record);
126 return Record.Processed.Task;
130 TaskCompletionSource<T> Waiter = this.subscribers.First.Value;
131 this.subscribers.RemoveFirst();
132 this.countSubscribers--;
133 Waiter.TrySetResult(Item);
135 return Task.FromResult(
true);
152 return Task.FromResult<T>(
null);
154 if (this.queue.First is
null)
156 TaskCompletionSource<T> Task =
new TaskCompletionSource<T>();
157 this.subscribers.AddLast(Task);
158 this.countSubscribers++;
163 Record = this.queue.First.Value;
164 this.queue.RemoveFirst();
167 Record.Processed.TrySetResult(
true);
169 if (this.terminated && this.queue.First is
null)
170 this.disposed =
true;
172 return Task.FromResult(Record.Value);
176 this.RaiseDisposed();
178 return Task.FromResult(Record.Value);
203 private bool TryGetItem(
bool Remove, out T Item)
207 if (this.disposed || this.queue.First is
null)
214 Item Record = this.queue.First.Value;
219 this.queue.RemoveFirst();
222 Record.Processed.TrySetResult(
true);
224 if (this.terminated && this.queue.First is
null)
225 this.disposed =
true;
234 this.RaiseDisposed();
248 this.disposed =
true;
249 this.terminated =
true;
251 foreach (Item Record
in this.queue)
252 Record.Processed.TrySetResult(
false);
257 foreach (TaskCompletionSource<T> Task
in this.subscribers)
258 Task.TrySetResult(
null);
260 this.subscribers.Clear();
261 this.countSubscribers = 0;
264 this.RaiseDisposed();
276 this.terminated =
true;
278 if (this.queue.First is
null)
280 this.disposed =
true;
282 foreach (Item Record
in this.queue)
283 Record.Processed.TrySetResult(
false);
288 foreach (TaskCompletionSource<T> Task
in this.subscribers)
289 Task.TrySetResult(
null);
291 this.subscribers.Clear();
292 this.countSubscribers = 0;
295 return this.terminatedTask.Task;
298 this.RaiseDisposed();
299 return this.terminatedTask.Task;
307 private void RaiseDisposed()
309 this.terminatedTask.TrySetResult(
true);
316 h(
this, EventArgs.Empty);
Static class managing the application event log. Applications and services log events on this static ...
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
Asynchronous First-in-First-out (FIFO) Queue, for use when transporting items of type T between task...
Task Terminate()
Terminates the queue, allowing subscribers to get queued items, but disallows new items to be added....
Task< bool > AddFirst(T Item)
Adds an item first to the queue.
Task< T > Wait()
Waits indefinitely (or until queue is disposed) for an item to be available. If Queue is disposed,...
int CountSubscribers
Number of subscribers waiting for items.
bool TryGetItem(out T Item)
Tries to get a queued item, if found. If not, the method returns immediately with a null item.
void Dispose()
IDisposable.Dispose
EventHandler Disposed
Event raised when queue has been disposed.
Task< bool > AddLast(T Item)
Adds an item last to the queue.
AsyncQueue()
Asynchronous Queue, for use when transporting items of class T between tasks.
Task< bool > Add(T Item)
Adds an item last to the queue.
Task< bool > Add(T Item, bool First)
Adds an item to the queue.
int CountItems
Number of items in queue.
bool TryPeekItem(out T Item)
Tries to get a queued item, if found. If not, the method returns immediately with a null item.