【问题标题】:Yield return in parallel并行收益回报
【发布时间】:2017-09-19 00:26:21
【问题描述】:

我有一个网络应用程序,它允许用户提交一个可以有许多长时间运行的任务的作业。我正在使用 yield return 来允许 Web 应用显示进度条,但这会强制同步执行。

我想做的是获取我的任务列表,并行运行它们,但仍向用户提供反馈。

在下面的代码中,我仍然想在每次调用 Infer 后产生 return,但我想并行运行循环。如果这无法通过 yield 实现,那么我有什么选择?

更具体地说,我想做的是将请求拆分为较小的集合,并让这些较小的集合并行运行。

出于问题的目的,假设我想将“请求”拆分为“请求 1”和“请求 2”,然后并行运行,但仍然能够在每个项目完成后返回给调用者。

    public IEnumerable<AnnotationRequest> Infer(List<Uri> fileUris, CancellationToken? token)
    {
        var requests = fileUris.Select(uri => new AnnotationRequest() { Uri = uri }).ToList();

        foreach ( var result in Infer(requests, token) )
        {
            yield return result;
        }
    }

【问题讨论】:

  • 您的问题似乎很广泛。有很多不同的方法可以接近它。您是否尝试过为每个组启动单独的任务并将每个结果添加到 BlockingCollection() 的组合,您在上面的 main 方法/线程中通过 GetConsumingEnumerable() 枚举?

标签: c# parallel-processing task-parallel-library yield-return


【解决方案1】:

感谢上面的 Peter Duniho 评论,我按照他的建议实施了它并且工作正常。

           var collection = new BlockingCollection<AnnotationRequest>();

           Task.Run(() =>
           {
               Parallel.ForEach(requests, (request) =>
              {
                  foreach (var result in Infer(request, token))
                  {
                      collection.Add(result);
                  }
              });

               collection.CompleteAdding();
           });

            foreach (var result in collection.GetConsumingEnumerable())
            {
                yield return result;
            }

【讨论】:

    猜你喜欢
    • 2011-05-27
    • 2012-01-14
    • 1970-01-01
    • 1970-01-01
    • 2018-01-23
    • 2010-12-01
    • 1970-01-01
    • 2011-01-13
    相关资源
    最近更新 更多