运行 个批处理任务

Run tasks in a batch

我正在尝试理解 System.Task,但我不确定我所做的是否正确。我的目标是写一个批量并行处理图像的方法。

我的理解是否正确,在 batchSize = 3 的情况下,该方法将在 Task.WaitAll() 被调用后立即将 3 个任务和 运行 所有 3 个任务并行排队?

有没有更优雅的做法?

private static void ProcessImages(int batchSize)
{
      List<Task> tasks = new List<Task>();
      foreach (var image in ImageSource.ReadImages())
      {
            if(tasks.Count < batchSize)
            { 
                 tasks.Add(Task.Run(() => ImageProcessor.ProcessImage(image)));
            }
            else
            {
                 Task.WaitAll(tasks.ToArray());
                 tasks.Clear();
            }
      }
}

Is my understanding correct, that in case of batchSize = 3 the method will queue 3 tasks and run all 3 tasks in parallel as soon as Task.WaitAll() being called ?

虽然将任务添加到列表然后 Task.WaitAll() 这些任务的想法是正确的,但不幸的是您的代码存在错误,无法按预期工作。具体来说,如果图像数量不能被 batchSize+1.

整除,它将不会执行每批次之后的图像任务,也不会执行最后一批图像的任务。

Is there are more elegant way if doing it ?

幸运的是,批量执行任务是非常普遍的要求,因此 .NET 已经包含了使它变得更容易的方法。使用 PLINQ 就这么简单:

ImageSource.ReadImages()
    .AsParallel()
    .WithDegreeOfParallelism(batchSize)
    .ForAll(image => ImageProcessor.ProcessImage(image));

另一种选择是使用 Microsoft 的 Reactive Framework (NuGet "System.Reactive")。

然后这有效:

ImageSource
    .ReadImages()
    .ToObservable()
    .Select(image => Observable.Start(() => ImageProcessor.ProcessImage(image)))
    .Merge(maxConcurrent: 3)
    .Wait();

恕我直言,Reactive Framework 比任务强大得多。