【问题标题】:Limit number of tasks with TPL使用 TPL 限制任务数
【发布时间】:2013-04-15 09:45:27
【问题描述】:

我正在研究创建需要在多个线程上执行的任务。我可以创建大量任务,例如 2000 个。我想限制同时排队和执行的任务数量。有没有办法创建一定数量的任务,然后在完成时创建新的任务?尝试确定任务调度程序是否对此有帮助。

编辑:

换一种说法……我是否有理由要限制同时创建/排队/执行的任务的数量,因为我可能有一个非常大的数字,例如2000. 任务调度程序是否以最佳方式调度任务,似乎找不到任何关于它实际工作方式的信息......

编辑:

我没有使用 Parallel.Foreach。我决定使用计数器,并根据最大数量的计数器和当前的任务数,创建任务或等到不超过最大数。

【问题讨论】:

  • 搜索MaxDegreeOfParallelism的主题。好像讨论过很多次了
  • 谢谢。我确实遇到过这些帖子,但似乎您需要指定核心数量,我不明确知道有多少核心或多少任务可以同时运行而不会造成瓶颈......而且似乎并行运行也使用阻塞?
  • 你能解释一下你到底想做什么吗?为什么你有这么多Tasks,你在处理一些收藏吗?如果你这样做了,Parallel.ForEach() 或 PLINQ 会为你工作吗?
  • “我没有使用 Parallel.Foreach。”你能解释一下为什么不吗?它看起来正是你所需要的,但如果你不告诉我们它实际上是什么就很难说。
  • @svick 根据我所读到的有关 parallel.foreach 的内容(我可能是错的),它会阻止所有处理,直到每项任务完成。我还需要创建任务发送大约 2000 封电子邮件,我真的不希望它阻止任何进一步的处理。另外,我正在尝试控制产生的线程数。我希望进行某种轮询,所以它只创建 x 个线程,如果超过最大值,它会等待一个空闲线程。

标签: .net task-parallel-library


【解决方案1】:

如果您想发送 2000 封电子邮件,并且不想阻塞当前线程并且只想使用有限数量的线程,那么我认为您应该使用调用 Parallel.ForEach() 的单个 Task。比如:

List<Email> emails = …;

var task = Task.Factory.StartNew(() =>
{
    Parallel.ForEach(
        emails,
        new ParallelOptions { MaxDegreeOfParallelism = maxNumberOfThreads },
        email => email.Send());
});

// handle the completion of task here

如果您不知道最佳线程数,那么您将不得不通过实验找到它。 TPL 能够合理地猜测 CPU 密集型计算的最佳线程数。但是您的代码不是 CPU 绑定的,而是网络绑定的,这意味着最佳线程数与 CPU 的内核数无关,它取决于网络连接的带宽和延迟(也可能您的邮件服务器)。

【讨论】:

    【解决方案2】:

    在评论中回复问题:

    “我不明确知道有多少核心......”

    您可以使用Environment.ProcessorCount 获取内核数量并使用它们来设置MaxDegreeOfParallelism

    ParallelOptions po = new ParallelOptions
    { 
        MaxDegreeOfParallelism = Environment.ProcessorCount
    };  
    

    是的,人们可能经常想要限制或调整由并行任务(.NET 线程池)提供的新线程的默认生成。这样的讨论很多:

    【讨论】:

    • 但这里的问题似乎与Parallel.ForEach()无关。
    猜你喜欢
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多