如何限制Parallel.ForEach?


295

我有一个Parallel.ForEach()异步循环,可以通过该循环下载一些网页。我的带宽有限,因此每次只能下载x页,但是Parallel.ForEach执行所需网页的整个列表。

在运行Parallel.ForEach时,是否可以限制线程数或任何其他限制器?

演示代码:

Parallel.ForEach(listOfWebpages, webpage => {
  Download(webpage);
});

真正的任务与网页无关,因此创造性的网络爬网解决方案将无济于事。


@jKlaus如果未修改列表(例如,它只是一组URL),我真的看不到问题吗?
2016年

@Shiv,如果有足够的时间,您将...计算执行次数并将其与列表的计数进行比较。
jKlaus

@jKlaus您在说什么会出错?
2016年

1
@jKlaus您正在修改一个非线程安全的元素(整数)。我希望它在那种情况下不起作用。另一方面,OP不会修改任何需要线程安全的内容。
Shiv

2
@jKlaus这是Parallel.ForEach的示例,可正确设置计数> dotnetfiddle.net/moqP2C。MSDN链接:msdn.microsoft.com/en-us/library/dd997393
v=vs.110).aspx

Answers:


564

您可以MaxDegreeOfParallelismParallelOptions参数中指定:

Parallel.ForEach(
    listOfWebpages,
    new ParallelOptions { MaxDegreeOfParallelism = 4 },
    webpage => { Download(webpage); }
);

MSDN:Parallel.ForEach

MSDN:ParallelOptions.MaxDegreeOfParallelism


59
它可能不适用于此特定情况,但我认为我会把它扔掉,以防任何人对此感到惊讶并发现它有用。在这里,我使用了处理器数量的75%(向上舍入)。 var opts = new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 1.0)) };
jKlaus 2015年

4
只是为了避免其他任何人不得不在文档中查找它,传递一个值与-1根本不指定它相同:“如果[value]为-1,则并发运行的操作数没有限制”
斯图尔特(Stuartd)2016年

从文档中对我来说还不清楚-将MaxDegreeOfParallelism设置为4(例如)是否意味着将有4个线程各自运行循环迭代的1/4(分配了4个线程的一轮),还是每个线程仍在执行一个循环迭代,我们只是限制了并行运行的数量?
哈什曼

7
需要明确的是,内核和线程不是同一回事。根据CPU,每个内核有不同数量的线程,通常每个内核2个。例如,如果您有一个4核CPU,每个核有2个线程,那么最多有8个线程。调整@jKlaus评论var opts = new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 2.0)) };。链接到线程VS核心- askubuntu.com/questions/668538/...
TheMiddleMan

41

您可以使用ParallelOptions并设置MaxDegreeOfParallelism来限制并发线程数:

Parallel.ForEach(
    listOfwebpages, 
    new ParallelOptions{MaxDegreeOfParallelism=2}, 
    webpage => {Download(webpage);});     

21

的使用另一个重载Parallel.Foreach采用一个ParallelOptions实例,并设置MaxDegreeOfParallelism到极限多少实例并行执行。


11

对于VB.net用户(语法很奇怪并且很难找到)...

Parallel.ForEach(listOfWebpages, New ParallelOptions() With {.MaxDegreeOfParallelism = 8}, Sub(webpage)
......end sub)  
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.