using System.Collections.Generic;
using System.Threading.Tasks;
public static void Main()
DataTable dt = ProcessAllAsync(Enumerable.Range(0, 10).Select(i => new InputObject { x = i })).Result;
foreach (DataRow row in dt.Rows)
Console.WriteLine(row[0].ToString());
Console.WriteLine("Done.");
static FinalObject Process(InputObject o)
return new FinalObject { x = o.x };
static async Task<DataTable> ProcessAllAsync(IEnumerable<InputObject> allData)
DataTable table = CreateTable();
int maxDegreeOfParallelism = Environment.ProcessorCount;
await ParallelForEachAsync(
FinalObject o = await Task.Run(() => Process(dataObj)).ConfigureAwait(false);
await Task.Delay(50).ConfigureAwait(false);
moveObj => table.Rows.Add(moveObj.x)
static async Task ParallelForEachAsync<TInput, TResult>(IEnumerable<TInput> input,
int maxDegreeOfParallelism,
Func<TInput, Task<TResult>> body,
Action<TResult> onCompleted)
Queue<TInput> queue = new Queue<TInput>(input);
List<Task<TResult>> tasksInFlight = new List<Task<TResult>>(maxDegreeOfParallelism);
while (tasksInFlight.Count < maxDegreeOfParallelism && queue.Count != 0)
TInput item = queue.Dequeue();
Task<TResult> task = body(item);
Task<TResult> completedTask = await Task.WhenAny(tasksInFlight).ConfigureAwait(false);
tasksInFlight.Remove(completedTask);
TResult result = completedTask.GetAwaiter().GetResult();
while (queue.Count != 0 || tasksInFlight.Count != 0);
static DataTable CreateTable()
DataTable dt = new DataTable();
dt.Columns.Add("x", typeof(int));