C#TPL如何知道所有任务都完成了?

Yar*_*ara 8 c# task task-parallel-library

我有Loop生成任务.

码:

Task task = null;
foreach (Entity a in AAAA)
{
  // create the task 
  task = new Task(() => {
    myMethod(a);
  },  Token, TaskCreationOptions.None);
  task.Start();
}
Run Code Online (Sandbox Code Playgroud)

正如你在每次迭代中看到的那样,任务对象有了新的初始化(.. new Task(()=> ..)我怎么知道所有的任务都完成了?

Hen*_*man 23

我用一个替换它

 Parallel.ForEach(...,  () => myMethod(a), ...)
Run Code Online (Sandbox Code Playgroud)

然后,您将在ForEach结束时自动等待所有任务.

也许可以从一个单独的Task运行ForEach.

  • 问题是,创建任务的循环和Parallel.ForEach之间存在一些非常真实的性能问题/差异.虽然它们在许多情况下可能相似,但它们不应盲目地替代彼此来解决无关的问题. (3认同)

Sof*_*per 13

var allTasks = new List<Task>();
foreach (Entity a in AAAA)
{
  // create the task 
  task = new Task(() => {
    myMethod(a);
  },  Token, TaskCreationOptions.None);

  // Add the tasks to a list
  allTasks.Add(task);
  task.Start();
}

// Wait until all tasks are completed.
Task.WaitAll(allTasks.ToArray());
Run Code Online (Sandbox Code Playgroud)


Tom*_*cek 8

您需要保留对循环中创建的所有任务的引用.然后您可以使用该Task.WaitAll方法(请参阅MSDN参考).您可以创建一个数组并将任务分配给该数组的元素(在C#2.0中),也可以使用LINQ:

var tasks = 
   AAAA.Select((Entity a) => 
      Task.Factory.StartNew(() => { myMethod(a); },
         Token, TaskCreationOptions.None)).ToArray();
Task.WaitAll(tasks)
Run Code Online (Sandbox Code Playgroud)

如果您不需要(明确地)使用任务,那么Henk的使用建议Parallel.ForEach可能是更好的选择.