Skip to content

Instantly share code, notes, and snippets.

@KirillShlenskiy
Last active June 29, 2024 12:12
Show Gist options
  • Save KirillShlenskiy/12de215654339473a9e7 to your computer and use it in GitHub Desktop.
Save KirillShlenskiy/12de215654339473a9e7 to your computer and use it in GitHub Desktop.
/// <summary>
/// Executes the given async delegates in parallel,
/// up to the given maximum degree of parallelism.
/// </summary>
public static async Task InvokeAsync(IEnumerable<Func<Task>> taskFactories, int maxDegreeOfParallelism)
{
if (taskFactories == null) throw new ArgumentNullException(nameof(taskFactories));
if (maxDegreeOfParallelism <= 0) throw new ArgumentException(nameof(maxDegreeOfParallelism));
// Defensive copy. Similar to what Task.WhenAll/WhenAny does.
Func<Task>[] queue = taskFactories.ToArray();
if (queue.Length == 0) {
return;
}
List<Task> tasksInFlight = new List<Task>(maxDegreeOfParallelism);
int index = 0;
do
{
while (tasksInFlight.Count < maxDegreeOfParallelism && index < queue.Length)
{
Func<Task> taskFactory = queue[index++];
tasksInFlight.Add(taskFactory());
}
Task completedTask = await Task.WhenAny(tasksInFlight).ConfigureAwait(false);
await completedTask.ConfigureAwait(false); // Check result.
tasksInFlight.Remove(completedTask);
}
while (index < queue.Length || tasksInFlight.Count != 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment