/// <summary> /// Perform the specified async action on each element /// of the <see cref="List{T}"/> with the specified concurrency. /// </summary> public static Task ForEachAsync <T>(this IEnumerable <T> source, Func <T, Task> asyncAction, int concurrency, CancellationToken cancellationToken = default) { source.ThrowIfArgumentNull(nameof(source)); asyncAction.ThrowIfArgumentNull(nameof(asyncAction)); concurrency.ThrowIfArgumentOutOfRange(1, int.MaxValue, nameof(concurrency)); async Task ForEachInner() { int throwedCount = 0; void OnFault(Exception e) { Interlocked.Add(ref throwedCount, 1); throw e; } using (var tasks = new TaskSet(concurrency, OnFault)) { foreach (var x in source) { if (throwedCount > 0) { break; } cancellationToken.ThrowIfCancellationRequested(); await tasks.AddAsync(x, asyncAction).ConfigureAwait(false); } await tasks.WhenAll().ConfigureAwait(false); } } return(ForEachInner()); }