Tenho um cenário estranho. Tenho uma lista de grupos. Para cada grupo, preciso iniciar uma tarefa para todos os conteúdos, mas preciso garantir que o último valor em cada grupo seja executado por último. Função simplificada abaixo:
public async Task DoAllTheWork(IEnumerable<IGrouping<string, string>> groups)
{
var allTasks = new List<Task>();
foreach (var group in groups)
{
var tasksInGroup = new List<Task>();
var values = group.ToList();
// start tasks for all except last value
foreach (var value in values.SkipLast(1))
{
var theTask = SomeAsyncFunction(value);
allTasks.Add(theTask);
tasksInGroup.Add(theTask);
}
// start a task for last value once all previous tasks are done
var lastTask = Task.Run(async () =>
{
await Task.WhenAll(tasksInGroup);
SomeAsyncFunction(values.Last());
});
allTasks.Add(lastTask);
}
await Task.WhenAll(allTasks);
}
Isso funciona bem. O problema é que todas as tarefas são executadas de uma vez, o que pode acabar sendo um problema se houver muitos grupos ou se os grupos tiverem muitos valores.
Gostaria de limitar o número de tarefas simultâneas sendo executadas. A maneira mais fácil que consigo pensar é que if allTasks
continha uma lista de tarefas que ainda não foram realmente iniciadas. Então eu poderia simplesmente fazer algo como:
Parallel.ForEach(allTasks, new ParallelOptions {MaxDegreeOfParallelism = 10},
aTask =>
{
aTask.Start();
});
Existe alguma maneira de fazer algo assim?