How to correctly write Parallel.For with async methods

后端 未结 4 750
夕颜
夕颜 2020-12-01 16:13

How would I structure the code below so that the async method gets invoked?

Parallel.For(0, elevations.Count(), delegate(int i)
{
   allSheets.AddRange(await         


        
4条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-01 16:30

    You can try this code I'm using. it using foreach and SemaphoreSlim to achive parallel asynchronous.

    public static class ParallelAsync
    {
        public static async Task ForeachAsync(IEnumerable source, int maxParallelCount, Func action)
        {
            using (SemaphoreSlim completeSemphoreSlim = new SemaphoreSlim(1))
            using (SemaphoreSlim taskCountLimitsemaphoreSlim = new SemaphoreSlim(maxParallelCount))
            {
                await completeSemphoreSlim.WaitAsync();
                int runningtaskCount = source.Count();
    
                foreach (var item in source)
                {
                    await taskCountLimitsemaphoreSlim.WaitAsync();
    
                    Task.Run(async () =>
                    {
                        try
                        {
                            await action(item).ContinueWith(task =>
                            {
                                Interlocked.Decrement(ref runningtaskCount);
                                if (runningtaskCount == 0)
                                {
                                    completeSemphoreSlim.Release();
                                }
                            });
                        }
                        finally
                        {
                            taskCountLimitsemaphoreSlim.Release();
                        }
                    }).GetHashCode();
                }
    
                await completeSemphoreSlim.WaitAsync();
            }
        }
    }
    

    usage:

    string[] a = new string[] {
        "1",
        "2",
        "3",
        "4",
        "5",
        "6",
        "7",
        "8",
        "9",
        "10",
        "11",
        "12",
        "13",
        "14",
        "15",
        "16",
        "17",
        "18",
        "19",
        "20"
    };
    
    Random random = new Random();
    
    await ParallelAsync.ForeachAsync(a, 2, async item =>
    {
        Console.WriteLine(item + " start");
    
        await Task.Delay(random.Next(1500, 3000));
        Console.WriteLine(item + " end");
    });
    
    Console.WriteLine("All finished");
    

    any suggestion please let me know.

提交回复
热议问题