コード例 #1
0
        /// <summary>
        /// Attempts to enqueue an item to any of a number of producer/consumer queues. Returns the producer/consumer queue that received the item. Returns <c>null</c> if all producer/consumer queues have completed adding.
        /// </summary>
        /// <param name="queues">The producer/consumer queues.</param>
        /// <param name="item">The item to enqueue.</param>
        /// <param name="cancellationToken">A cancellation token that can be used to abort the enqueue operation.</param>
        /// <returns>The producer/consumer queue that received the item.</returns>
        public static async Task <AsyncProducerConsumerQueue <T> > TryEnqueueToAnyAsync <T>(this IEnumerable <AsyncProducerConsumerQueue <T> > queues, T item, CancellationToken cancellationToken)
        {
            var abort = new TaskCompletionSource();

            using (var abortCancellationToken = CancellationTokenHelpers.FromTask(abort.Task))
                using (var combinedToken = CancellationTokenHelpers.Normalize(abortCancellationToken.Token, cancellationToken))
                {
                    var token   = combinedToken.Token;
                    var tasks   = queues.Select(q => q.TryEnqueueAsync(item, token, abort));
                    var results = await TaskShim.WhenAll(tasks).ConfigureAwait(false);

                    var ret = results.FirstOrDefault(x => x != null);
                    if (ret == null)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                    }
                    return(ret);
                }
        }
コード例 #2
0
        /// <summary>
        /// Attempts to take an item from any of a number of producer/consumer collections. The operation "fails" if all the producer/consumer collections have completed adding and are empty, or if any take operation on an underlying collection fails.
        /// </summary>
        /// <param name="collections">The producer/consumer collections.</param>
        /// <param name="cancellationToken">A cancellation token that can be used to abort the take operation.</param>
        public static async Task <AsyncCollection <T> .TakeResult> TryTakeFromAnyAsync <T>(this IEnumerable <AsyncCollection <T> > collections, CancellationToken cancellationToken)
        {
            var abort = new TaskCompletionSource();

            using (var abortCancellationToken = CancellationTokenHelpers.FromTask(abort.Task))
                using (var combinedToken = CancellationTokenHelpers.Normalize(abortCancellationToken.Token, cancellationToken))
                {
                    var token   = combinedToken.Token;
                    var tasks   = collections.Select(q => q.TryTakeAsync(token, abort));
                    var results = await TaskShim.WhenAll(tasks).ConfigureAwait(false);

                    var result = results.FirstOrDefault(x => x.Success);
                    if (result != null)
                    {
                        return(result);
                    }
                    cancellationToken.ThrowIfCancellationRequested();
                    return(AsyncCollection <T> .FalseResult);
                }
        }