Je me demande s'il existe une implémentation/wrapper pour ConcurrentQueue, similaire à BlockingCollection où prélèvement de la collection ne bloque pas, mais est plutôt asynchrone et provoquera une attente asynchrone jusqu'à ce qu'un élément est placé dans le queue.attente Tâche basée sur la file d'attente
J'ai trouvé ma propre implémentation, mais elle ne semble pas fonctionner comme prévu. Je me demande si je réinvente quelque chose qui existe déjà.
Voici mon implémentation:
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 beurk .... ...... –
@AdamSack: en effet, mais votre commentaire ne m'aide pas. – spender