Menu

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.

Leave a comment