Parallel.ForEach如何知道哪个项目? - 哪个循环?

Mon*_*RPG 2 c# parallel.foreach

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

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

  Parallel.ForEach(lstAllUrls, options, myFunctionThatFetchPage);
Run Code Online (Sandbox Code Playgroud)

现在这完全没问题.我想知道的是:我怎么知道我目前在哪个迭代.我的意思是说我的列表有100000个URL.它开始取出它们.但我还想在屏幕上打印当前正在获取URL的内容.

我怎样才能做到这一点?如何判断循环当前在给定列表的哪个项目?

ale*_*lex 10

您可以使用以下过载Parallel.ForEach:

public static ParallelLoopResult ForEach<TSource>(
    IEnumerable<TSource> source,
    Action<TSource, ParallelLoopState, long> body
)
Run Code Online (Sandbox Code Playgroud)

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


das*_*ght 5

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

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)