【问题标题】:How can I limit Parallel.ForEach?如何限制 Parallel.ForEach?
【发布时间】:2023-04-06 04:30:01
【问题描述】:

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

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

演示代码:

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

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

【问题讨论】:

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

标签: c# .net asynchronous parallel.foreach


【解决方案1】:

您可以在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(例如)是否意味着将有 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/…
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-18
        相关资源
        最近更新 更多