Ejemplo n.º 1
0
        private static async Task RunLoopAsync <T>(
            EnumeratorInfo <T> enumerator,
            T item,
            int index,
            ConcurrentQueue <Exception> exceptions,
            Func <T, int, CancellationToken, Task> func,
            CancellationToken cancelToken)
        {
            do
            {
                if (exceptions.Count > 0)
                {
                    return;
                }

                try
                {
                    await func(item, index, cancelToken).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    exceptions.Enqueue(ex);
                    return;
                }
            }while (enumerator.TryGetNext(out item, out index));
        }
Ejemplo n.º 2
0
        public static async Task WhenAll <T>(
            this IEnumerable <T> enumerable,
            CancellationToken cancelToken,
            Func <T, int, CancellationToken, Task> func,
            int?maxParallelization = null)
        {
            if (enumerable == null)
            {
                throw new ArgumentNullException(nameof(enumerable));
            }

            if (func == null)
            {
                throw new ArgumentNullException(nameof(func));
            }

            var exceptions = new ConcurrentQueue <Exception>();
            var maxCount   = maxParallelization ?? Environment.ProcessorCount;
            var tasks      = new List <Task>(maxCount);

            using (var enumerator = new EnumeratorInfo <T>(enumerable))
            {
                for (var i = 0; i < maxCount; i++)
                {
                    T   item;
                    int index;
                    if (!enumerator.TryGetNext(out item, out index))
                    {
                        break;
                    }

                    var task = RunLoopAsync(enumerator, item, index, exceptions, func, cancelToken);
                    tasks.Add(task);
                }

                await Task.WhenAll(tasks).ConfigureAwait(false);
            }

            if (exceptions.Count > 0)
            {
                throw new AggregateException(exceptions);
            }
        }