internal AsyncProducerConsumerQueue <T> TryEnqueueInternal(T item, CancellationToken ct) { try { using (var source = CancellationTokenHelper.Aggregate(completed.Token, ct)) { using (mutex.Lock()) { while (IsFull) { notFull.Wait(source.Token); } if (completed.IsCancellationRequested) { return(null); } queue.Enqueue(item); completedOrNotEmpty.Notify(); return(this); } } } catch (OperationCanceledException) { return(null); } }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="queues"></param> /// <param name="ct"></param> /// <returns></returns> public static async Task <AsyncProducerConsumerQueue <T> .DequeueResult> TryDequeueFromAnyAsync <T>( this IEnumerable <AsyncProducerConsumerQueue <T> > queues, CancellationToken ct) { var abort = new TaskCompletionSource(); using (var cancellation = CancellationTokenHelper.FromTask(abort.Task)) { using (var aggregation = CancellationTokenHelper.Aggregate(cancellation.Token, ct)) { var token = aggregation.Token; var tasks = queues.Select(queue => queue.TryDequeueAsync(token, abort)); var results = await Task.WhenAll(tasks).ConfigureAwait(false); var result = results.FirstOrDefault(value => value.Success); if (null != result) { return(result); } ct.ThrowIfCancellationRequested(); return(AsyncProducerConsumerQueue <T> .FalseResult); } } }
internal async Task <AsyncProducerConsumerQueue <T> > TryEnqueueAsync(T item, CancellationToken ct, TaskCompletionSource abort) { try { using (var source = CancellationTokenHelper.Aggregate(completed.Token, ct)) { using (await mutex.LockAsync().ConfigureAwait(false)) { while (IsFull) { await notFull.WaitAsync(source.Token).ConfigureAwait(false); } if (completed.IsCancellationRequested) { return(null); } if (null != abort && false == abort.TrySetCanceled()) { return(null); } queue.Enqueue(item); completedOrNotEmpty.Notify(); return(this); } } } catch (OperationCanceledException) { return(null); } }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="queues"></param> /// <param name="item"></param> /// <param name="ct"></param> /// <returns></returns> public static async Task <AsyncProducerConsumerQueue <T> > TryEnqueueToAnyAsync <T>( this IEnumerable <AsyncProducerConsumerQueue <T> > queues, T item, CancellationToken ct) { var abort = new TaskCompletionSource(); using (var cancellation = CancellationTokenHelper.FromTask(abort.Task)) { using (var aggregation = CancellationTokenHelper.Aggregate(cancellation.Token, ct)) { var token = aggregation.Token; var tasks = queues.Select(queue => queue.TryEnqueueAsync(item, token, abort)); var results = await Task.WhenAll(tasks).ConfigureAwait(false); var candidate = results.FirstOrDefault(value => null != value); if (null == candidate) { ct.ThrowIfCancellationRequested(); } return(candidate); } } }