Zastanawiam się, czy istnieje implementacja/opakowanie dla ConcurrentQueue, podobne do BlockingCollection, gdzie pobieranie z kolekcji nie blokuje, ale jest zamiast tego asynchroniczne i spowoduje asynchronizację, aż element zostanie umieszczony w kolejka.godna uwagi Kolejka na podstawie zadania
Wymyśliłem własną implementację, ale wygląda na to, że nie działa zgodnie z oczekiwaniami. Zastanawiam się, czy wymyślam coś, co już istnieje.
Oto moja realizacja:
public class MessageQueue<T>
{
ConcurrentQueue<T> queue = new ConcurrentQueue<T>();
ConcurrentQueue<TaskCompletionSource<T>> waitingQueue =
new ConcurrentQueue<TaskCompletionSource<T>>();
object queueSyncLock = new object();
public void Enqueue(T item)
{
queue.Enqueue(item);
ProcessQueues();
}
public async Task<T> Dequeue()
{
TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
waitingQueue.Enqueue(tcs);
ProcessQueues();
return tcs.Task.IsCompleted ? tcs.Task.Result : await tcs.Task;
}
private void ProcessQueues()
{
TaskCompletionSource<T> tcs=null;
T firstItem=default(T);
while (true)
{
bool ok;
lock (queueSyncLock)
{
ok = waitingQueue.TryPeek(out tcs) && queue.TryPeek(out firstItem);
if (ok)
{
waitingQueue.TryDequeue(out tcs);
queue.TryDequeue(out firstItem);
}
}
if (!ok) break;
tcs.SetResult(firstItem);
}
}
}
oh fuj .... ...... –
@AdamSack: rzeczywiście, ale twój komentarz mi nie pomoże. – spender