public static async Task ParallelForEachAsync <T>( this IEnumerable <T> source, Func <T, int, Task> asyncAction, int?maxDegreeOfParallelism = null) { if (maxDegreeOfParallelism == 1) { await source.ForEachAsync(asyncAction); return; } maxDegreeOfParallelism ??= Math.Min(Environment.ProcessorCount, 512); OrderablePartitioner <T> partitioner = source is IList <T> list ? Partitioner.Create(list, loadBalance : true) : Partitioner.Create(source, EnumerablePartitionerOptions.NoBuffering); await Task.WhenAll(partitioner .GetPartitions(maxDegreeOfParallelism.Value) .Select((partition, index) => Task.Run(async() => { while (partition.MoveNext()) { await asyncAction(partition.Current, index); } }))); }
public static async Task ParallelForEachAsync <T>( this IEnumerable <T> source, Func <T, Task> asyncAction, int?maxDegreeOfParallelism = null) { maxDegreeOfParallelism ??= DefaultMaxDegreeOfParallelism; if (maxDegreeOfParallelism <= 0) { throw new ArgumentOutOfRangeException(nameof(maxDegreeOfParallelism)); } if (maxDegreeOfParallelism == 1) { foreach (T value in source) { await asyncAction(value); } return; } OrderablePartitioner <T> partitioner = source is IList <T> list ? Partitioner.Create(list, loadBalance : true) : Partitioner.Create(source, EnumerablePartitionerOptions.NoBuffering); await Task.WhenAll(partitioner .GetPartitions(maxDegreeOfParallelism.Value) .Select(async partition => { while (partition.MoveNext()) { await asyncAction(partition.Current); } })); }
public override IList <IEnumerator <TSource> > GetPartitions(int partitionCount) { return(_partitioner.GetPartitions(partitionCount)); }