【问题标题】:Parallel.ForEach how to know at which item ? - which loop?Parallel.ForEach 如何知道在哪个项目? - 哪个循环?
【发布时间】:2013-05-01 11:19:08
【问题描述】:

例子

  var options = new ParallelOptions()
  {
      MaxDegreeOfParallelism = 10
  };

  List<string> lstAllUrls = File.ReadAllLines("myList.txt").ToList<string>();

  Parallel.ForEach(lstAllUrls, options, myFunctionThatFetchPage);

现在这工作得很好。我想知道的是:我如何知道我目前处于哪个迭代中。我的意思是说我的列表有 100000 个 URL。它开始获取它们。但我也想在屏幕上打印当前正在获取的 URL。

我该怎么做?如何判断当前循环位于给定列表的哪一项?

【问题讨论】:

  • 您应该在myFunctionThatFetchPage 中执行此操作。例如,在函数的开头,您可以将 url 添加到列表中,并在最后将其删除。请注意,根据您要更新的内容,您可能需要在更新列表时回调 UI 线程。
  • 你不知道url的处理顺序,会并行运行。
  • @GeorgeDuckett 感谢这是一个选项。我想知道在 for 循环中是否有任何索引。
  • @Jodrell 我唯一想知道的就是它正在处理 url 列表中的 url。我的意思是 foreach 必须有一个索引才能知道接下来要处理哪个项目。
  • 报告进度而不是它当前正在处理的索引可能更有意义。即在你的函数中只增加一个计数器并显示它。

标签: c# parallel.foreach


【解决方案1】:

您可以使用以下overloadParallel.ForEach

public static ParallelLoopResult ForEach<TSource>(
    IEnumerable<TSource> source,
    Action<TSource, ParallelLoopState, long> body
)

它将在第三个参数中将当前元素索引传递给您的委托。

【讨论】:

  • 感谢您的回答,但我不知道如何在我的代码中使用它。
  • myFunctionThatFetchPage 应声明为 void myFunctionThatFetchPage (string p1, ParallelLoopState p2, long p3)
  • 告诉你项目在列表中的索引位置。不一定是它们的处理顺序。
  • 感谢 alex 现在这更有意义了。所以 p3 是索引号还是 p2 ?
  • 或使用 lambda:Parallel.ForEach(lstAllUrls, options, (x, y, i) =&gt; { ... });。在大括号内,x 是您的项目(网址),i 是当前索引。
【解决方案2】:

由于项目是并行提供给您的 URL 处理委托的,因此它可能会“看到”您的列表索引不按顺序,即,将提供较高索引的项目将在具有较低索引的项目之前进行处理。这通常不是您想要的 "M out of N" 消息。

解决此问题的一种方法是在与ForEach 机制分开设置的计数器上使用Interlocked.Increment

private int count;
...
void MyForEachDelegate(string urlStr) {
    ...
    int pos = Interlocked.Increment(ref count);
    if ((pos-1) % 1000 == 0) {
        Console.WriteLine("Processing URL number {0}", pos);
    }
}

【讨论】:

    【解决方案3】:

    AFAIK,Parallel.ForEach 就像它的表亲 foreach - 不擅长知道它在哪个迭代。您可以改用 Parallel.For 并使用循环变量来告诉位置。一般来说,请记住,您在循环中所做的任何访问共享资源的操作都可能会降低并行度,因此不要过度使用进度条码等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-02
      • 2011-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多