Skip to content

Instantly share code, notes, and snippets.

@0xced
Created May 26, 2018 17:57
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save 0xced/94f6c50d620e582e19913742dbd76eb6 to your computer and use it in GitHub Desktop.
Save 0xced/94f6c50d620e582e19913742dbd76eb6 to your computer and use it in GitHub Desktop.
Parallel foreach async enumeration with maximum degree of parallelism
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Parallel
{
public static class EnumerableExtensions
{
// Adapted from https://blogs.msdn.microsoft.com/pfxteam/2012/03/05/implementing-a-simple-foreachasync-part-2/
public static Task ForEachAsync<T>(this IEnumerable<T> source, int degreeOfParallelism, Func<T, Task> body, IProgress<T> progress = null)
{
return Task.WhenAll(
Partitioner.Create(source).GetPartitions(degreeOfParallelism)
.Select(partition => Task.Run(async () => {
using (partition)
while (partition.MoveNext())
{
await body(partition.Current);
progress?.Report(partition.Current);
}
}))
);
}
}
}
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Parallel;
class Program
{
static async Task Main()
{
var random = new Random();
var delays = Enumerable.Range(0, 42).Select(_ => random.Next(0, 100)).ToList();
IProgress<int> progress = new Progress<int>(i => Console.Write($"{i} "));
var stopwatch = Stopwatch.StartNew();
foreach (var i in delays)
{
await Task.Delay(i);
progress.Report(i);
}
Console.WriteLine($"{Environment.NewLine}Sequential execution: {stopwatch.Elapsed.TotalSeconds} seconds");
stopwatch.Restart();
await delays.ForEachAsync(10, async i => await Task.Delay(i), progress);
Console.WriteLine($"{Environment.NewLine}Parallel execution: {stopwatch.Elapsed.TotalSeconds} seconds");
}
}
@uchinago
Copy link

I want to return an Tuple<bool, Ienumerable> from my async how do you incorporate this and collect the result of each task.
bool would be the complex task completed successfully or not, List would be any error messages

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment