平行的.每个人怎么知道在哪个项目?-哪个循环
本文关键字:项目 循环 每个人 | 更新日期: 2023-09-27 18:11:34
示例
var options = new ParallelOptions()
{
MaxDegreeOfParallelism = 10
};
List<string> lstAllUrls = File.ReadAllLines("myList.txt").ToList<string>();
Parallel.ForEach(lstAllUrls, options, myFunctionThatFetchPage);
现在这工作得很好。我想知道的是:我如何知道我目前处于哪个迭代。假设我的列表有100000个url。它开始获取它们。但我还想在屏幕上打印当前哪个URL正在被获取
我该怎么做呢?我如何知道当前循环在给定列表的哪一项?
您可以使用以下Parallel.ForEach
的重载:
public static ParallelLoopResult ForEach<TSource>(
IEnumerable<TSource> source,
Action<TSource, ParallelLoopState, long> body
)
它将在第三个参数中将当前元素索引传递给您的委托。
由于项目是并行提供给您的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);
}
}
很好,平行。ForEach就像它的表兄ForEach——不擅长知道它在哪个迭代。你可以用Parallel。而使用循环变量来告诉位置。通常要记住,在循环中访问共享资源的任何操作都可能降低并行度,所以不要过度使用进度条或类似的代码。