using System.Diagnostics;
using System.Collections.Generic;
using System.Threading.Tasks;
class ConsoleTimer : IDisposable
private readonly Stopwatch _stopwatch;
_stopwatch = new Stopwatch();
Console.WriteLine("Duration: {0}ms", _stopwatch.ElapsedMilliseconds);
public static async Task<IEnumerable<TResult>> ExecTasksInParallelAsync1<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, Task<TResult>> task, int minDegreeOfParallelism = 1, int maxDegreeOfParallelism = 1)
var allTasks = new List<Task<TResult>>();
using (var throttler = new SemaphoreSlim(minDegreeOfParallelism, maxDegreeOfParallelism))
foreach (var element in source)
await throttler.WaitAsync();
Func<Task<TResult>> func = async () =>
return await task(element);
allTasks.Add(Task.Run(func));
return await Task.WhenAll(allTasks);
public static async Task<IEnumerable<TResult>> ExecTasksInParallelAsync2<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, Task<TResult>> task, int minDegreeOfParallelism = 1, int maxDegreeOfParallelism = 1)
var allTasks = new List<Task<TResult>>();
using (var throttler = new SemaphoreSlim(minDegreeOfParallelism, maxDegreeOfParallelism))
foreach (var element in source)
await throttler.WaitAsync();
Func<Task<TResult>> func = async () =>
return await task(element);
allTasks.Add(func.Invoke());
return await Task.WhenAll(allTasks);
public static async Task<IEnumerable<TResult>> ExecTasksInParallelAsync3<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, Task<TResult>> task, int minDegreeOfParallelism = 1, int maxDegreeOfParallelism = 1)
return source.AsParallel().WithDegreeOfParallelism(maxDegreeOfParallelism)
.Select(s => task(s).GetAwaiter().GetResult());
public static void Main()
MainAsync().GetAwaiter().GetResult();
Console.WriteLine("Press ENTER");
public static async Task<string> DoSomethingToAString(string input)
public static async Task MainAsync()
var list = Enumerable.Range(1, 10000).Select(i => string.Format("Testing({0})...", i)).ToList();
for (var run = 1; run<= 3; run++)
Console.WriteLine("Run {0}", run);
Console.Write("Option 1: ");
using (new ConsoleTimer())
for (int trial = 0; trial < 10; trial++)
var output = await Program.ExecTasksInParallelAsync1<string, string>(list, DoSomethingToAString, 1, 4);
Console.Write("Option 2: ");
using (new ConsoleTimer())
for (int trial = 0; trial < 10; trial++)
var output = await Program.ExecTasksInParallelAsync2<string, string>(list, DoSomethingToAString, 1, 4);
Console.Write("Option 3 :");
using (new ConsoleTimer())
for (int trial = 0; trial < 10; trial++)
var output = await Program.ExecTasksInParallelAsync3<string, string>(list, DoSomethingToAString, 1, 4);