Skip to content

Instantly share code, notes, and snippets.

@ctigeek
Created July 1, 2014 01:36
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ctigeek/2f67df6f1a3a68be3ceb to your computer and use it in GitHub Desktop.
Save ctigeek/2f67df6f1a3a68be3ceb to your computer and use it in GitHub Desktop.
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
Copy link

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