Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ParallelTaskRunnerExtension - Running tasks in parallel, but limiting the concurrency.
public static class ParallelTaskRunnerExtension
{
public static void RunTasks(this IEnumerable<Task> tasks, int maxConcurrency, Action<Task> taskComplete = null)
{
if (maxConcurrency <= 0) throw new ArgumentException("maxConcurrency must be more than 0.");
int taskCount = 0;
int nextIndex = 0;
var currentTasks = new Task[maxConcurrency];
foreach (var task in tasks)
{
currentTasks[nextIndex] = task;
taskCount++;
if (taskCount == maxConcurrency)
{
nextIndex = Task.WaitAny(currentTasks);
if (taskComplete != null)
{
taskComplete(currentTasks[nextIndex]);
}
currentTasks[nextIndex] = null;
taskCount--;
}
else
{
nextIndex++;
}
}
while (taskCount > 0)
{
currentTasks = currentTasks.Where(t => t != null).ToArray();
nextIndex = Task.WaitAny(currentTasks);
if (taskComplete != null)
{
taskComplete(currentTasks[nextIndex]);
}
currentTasks[nextIndex] = null;
taskCount--;
}
}
public static void RunTasks<T>(this IEnumerable<Task<T>> tasks, int maxConcurrency, Action<Task<T>> taskComplete = null)
{
if (maxConcurrency <= 0) throw new ArgumentException("maxConcurrency must be more than 0.");
int taskCount = 0;
int nextIndex = 0;
var currentTasks = new Task<T>[maxConcurrency];
foreach (var task in tasks)
{
currentTasks[nextIndex] = task;
taskCount++;
if (taskCount == maxConcurrency)
{
nextIndex = Task.WaitAny(currentTasks);
if (taskComplete != null)
{
taskComplete(currentTasks[nextIndex]);
}
currentTasks[nextIndex] = null;
taskCount--;
}
else
{
nextIndex++;
}
}
while (taskCount > 0)
{
currentTasks = currentTasks.Where(t => t != null).ToArray();
nextIndex = Task.WaitAny(currentTasks);
if (taskComplete != null)
{
taskComplete(currentTasks[nextIndex]);
}
currentTasks[nextIndex] = null;
taskCount--;
}
}
}
@rhinocerous

This comment has been minimized.

Copy link

rhinocerous commented Jul 20, 2017

I just wanted to say Thank You for this code and the outstanding article you wrote which explains your process and choices. I was able to adapt this to a prototype I am building and it works like a champion. I appreciate that you took the time to share this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.