代码之家  ›  专栏  ›  技术社区  ›  koryakinp

批量运行任务

  •  0
  • koryakinp  · 技术社区  · 7 年前

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

    batchSize = 3 该方法将对3个任务进行排队,并尽快并行运行所有3个任务 Task.WaitAll() 被叫去?

    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();
                }
          }
    }
    
    2 回复  |  直到 7 年前
        1
  •  5
  •   Ňuf    7 年前

    我的理解正确吗,在batchSize=3的情况下 将对3个任务进行排队,并尽快并行运行所有3个任务 正在调用Task.WaitAll()?

    Task.WaitAll() 这些任务是正确的,您的代码是不幸的错误,将无法按预期工作。具体地说,如果图像的数量不能被整除,它将不会对每个批之后的图像执行任务,也不会对最后一批中的图像执行任务 batchSize+1 .

    有没有更优雅的方法呢?

    幸运的是,分批执行任务是非常常见的要求,因此.NET已经包含了使之更容易的方法。具有 PLINQ 就这么简单:

    ImageSource.ReadImages()
        .AsParallel()
        .WithDegreeOfParallelism(batchSize)
        .ForAll(image => ImageProcessor.ProcessImage(image));
    
        2
  •  2
  •   Enigmativity    7 年前

    另一种选择是使用微软的反应式框架(NuGet“System.Reactive”)。

    这样就行了:

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