C# Task RunParallel

Date: 2020-09-08

Update 2022-12-22:

public static async Task<IEnumerable<T>> RunParallel<T>(int concurrency, IEnumerable<Func<Task<T>>> actions)
{
    using (var semaphore = new SemaphoreSlim(concurrency))
    {
        var tasks = new List<Task<T>>();
        foreach (var action in actions)
        {
            await semaphore.WaitAsync();
            var t = Task.Run(async () =>
            {
                try
                {
                    return await action();
                }
                finally
                {
                    semaphore.Release();
                }
            });
            tasks.Add(t);
        }
        return await Task.WhenAll(tasks);
    }
}

// example use:
var tasks = new List<Func<Task<bool>>>();
foreach (var myTask in myTasks)
{
    tasks.Add(() => myTask("A", "B"));
}
var results = await RunParallel(3, tasks);

Original:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    public static async Task RunParallel<T>(int concurrency, IEnumerable<T> args, Func<T, Task> action)
    {
        using (var semaphore = new SemaphoreSlim(concurrency))
        {
            var tasks = new List<Task>();
            foreach (var arg in args)
            {
                await semaphore.WaitAsync();

                var t = Task.Run(async () =>
                {
                    try
                    {
                        await action(arg);
                    }
                    finally
                    {
                        semaphore.Release();
                    }
                });

                tasks.Add(t);
            }
            await Task.WhenAll(tasks);
        }
    }

    static async Task Main(string[] args)
    {

        var arguments = Enumerable.Range(1, 15).Select(e => e.ToString()).ToList();
        await RunParallel(3, arguments, async (a) =>
        {
            Console.WriteLine("Start: " + a);
            await Task.Delay(2000);
            Console.WriteLine("End: " + a);
        });

        Console.WriteLine("Finished!");
    }
}
40220cookie-checkC# Task RunParallel