ChatGPT解决这个技术问题 Extra ChatGPT

如何限制 Parallel.ForEach?

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

有没有办法在运行 Parallel.ForEach 时限制线程数或任何其他限制器?

演示代码:

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

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

@jKlaus 如果列表没有被修改,例如它只是一组 URL,我真的看不出问题吗?
@Shiv,如果有足够的时间,您将...计算您的执行次数并将其与列表计数进行比较。
@jKlaus 你说什么会出错?
@jKlaus 您正在修改非线程安全元素(整数)。我希望它在那种情况下不起作用。另一方面,OP 没有修改任何需要线程安全的东西。
@jKlaus 这是一个正确设置计数的 Parallel.ForEach 示例 > dotnetfiddle.net/moqP2C。 MSDN 链接:msdn.microsoft.com/en-us/library/dd997393(v=vs.110).aspx

N
Nick Butler

您可以在 ParallelOptions 参数中指定 MaxDegreeOfParallelism

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

MSDN:Parallel.ForEach

MSDN:ParallelOptions.MaxDegreeOfParallelism


它可能不适用于这种特殊情况,但我想我会把它扔掉,以防有人对此感到疑惑并发现它有用。在这里,我使用了 75%(向上取整)的处理器数量。 var opts = new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 1.0)) };
只是为了节省其他人必须在文档中查找它,传递 -1 的值与根本不指定它是一样的:“如果 [值] 是 -1,则没有限制并发运行的操作数"
从文档中我不清楚 - 将 MaxDegreeOfParallelism 设置为 4(例如)是否意味着每个线程将运行 1/4 的循环迭代(一轮 4 个线程调度),或者每个线程仍然执行一个循环迭代,我们只是限制并行运行的数量?
需要明确的是核心和线程不是一回事。根据 CPU 的不同,每个内核有不同数量的线程,通常每个内核 2 个。例如,如果您有一个 4 核 CPU,每个内核有 2 个线程,那么您最多有 8 个线程。调整@jKlaus 评论 var opts = new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 2.0)) };。链接到线程与内核 - askubuntu.com/questions/668538/…
U
Uwe Keim

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

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

R
Richard

使用另一个采用 ParallelOptions 实例的 Parallel.Foreach 重载,并设置 MaxDegreeOfParallelism 以限制并行执行的实例数量。


u
user3496060

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

Parallel.ForEach(listOfWebpages, New ParallelOptions() With {.MaxDegreeOfParallelism = 8}, Sub(webpage)
......end sub)