C# running parallel asynchronous tasks with limited number of concurrent tasks (MaxDegreeOfParallelism)
I have recently started integration a web api service, there are more than 2000+ records to get and my input is different.
Ex : I need to get 100+ records for input “ABC”, 200+ records for input “BCE”, etc.
Option 1 (Simple loop with once call at a time)
Do a for loop and collect all the results and return you complete collection.
Option 2 (Task Array)
Easiest approach is the have a task array and do a Wait all for all of them to be completed before return.
private async Task<List<Model>> MyMethod(string[] allinputs) { var inputBatchs = allinputs.ToArray().Chunk(50); var availabilities = new List<Model>(); var tasks = new List<Task<IReadOnlyList<Model>>>(); foreach (var inputs in inputBatchs) { tasks.Add(GetEventBatchAsync(inputs)); } await Task.WhenAll(tasks); foreach (var task in tasks) { var events = await task; availabilities.AddRange(events); } return availabilities; } private async Task<IReadOnlyList<Model>> GetEventBatchAsync(string[] inputs) { return await _apiService.GetEventsAsync(inputs); }
But api service had a limitation of number of concurrent connections of 15. therefore my calls after 15th call, were failing.
Option 3 (Parallel)
private async Task<List<Model>> MyMethod(string[] allinputs) { var inputBatchs = allinputs.ToArray().Chunk(50); var availabilities = new List<Model>(); var options = new ParallelOptions { MaxDegreeOfParallelism = 15 }; await Parallel.ForEachAsync(inputBatchs , options, async (inputBatch, token) => { var events = await _apiService.GetEventsAsync(inputs) availabilities.AddRange(events); }); return availabilities; }
now the calls complete in 4 seconds vs option 1 where it took 40 seconds.