【问题标题】:Task.Factory.StartNew - confused about the poolTask.Factory.StartNew - 对池感到困惑
【发布时间】:2013-08-02 15:39:16
【问题描述】:

您好,我将自己与 Task.Factory.StartNew 捆绑在一起。正如我想我明白了,有人建议我编写以下代码;

bool exitLoop = false;                
while (!exitLoop)
{
    exitLoop = true;
    var messages = Queue.GetMessages(20);
    foreach (var message in messages)                    
    {
        exitLoop = false;
        Task.Factory.StartNew(() =>
                    {
                        DeliverMessage(message);
                    });
    }
}

理论上,这将耗尽一个队列,一次 20 条消息,尝试为队列中的每条消息创建一个任务。因此,如果我们在队列中有 1000 条消息,那么瞬间我们就会有 25 个任务,它会吃掉所有的消息。我以前认为我理解这一点,我认为 StartNew 一旦条目用完就会阻止 - 在过去应该是 ~ 25。但鉴于这是 .net 4.5,我现在的印象是上限一个游泳池现在相当高。让我感到困惑的是,我会假设这将用新任务淹没池并开始阻塞,即瞬间我现在有 1000 个任务在运行。那么,如果池限制现在几乎没有限制,为什么我看不到 1000 个任务?

[编辑] 好的,所以我看到的是 1000 个任务排队运行,而不是正在运行。那么如何确定运行/可运行任务的数量呢?

【问题讨论】:

  • Task.Factory 将立即或在调度程序找到可用线程时执行其队列中的每个任务。此外,在使用 StartNew 方法时需要传递取消令牌,以避免 GC 导致任务意外终止。我不确定如何确定运行/可运行任务的数量。
  • 另外我忘了说,任务池不会锁定任何东西,这就是为什么有一个任务调度器。
  • 您想知道当前正在运行的任务数或是否有任何任务未完成?
  • 基本上我只是想找到传递 1000 条消息的最佳方式,因为读取一条味精的成本为 C。所以通过使用并发,我希望能超过 1000C

标签: c# multithreading threadpool


【解决方案1】:

我知道这是您发布帖子后的一段时间,但我希望这可以帮助面临您特定挑战的人。您的最后一条评论指出“DeliverMessage”方法正在发出 HTTP 请求。

如果您使用“WebClient”对象(例如)发出请求,它将受ServicePointManager.DefaultConnectionLimit 属性的约束。这意味着它将最多创建两个(默认情况下)到主机的并发连接。如果您创建了 1,000 个并行任务,那么所有 1,000 个任务都必须由这两个连接提供服务。

您必须尝试使用​​此设置的不同值,才能在应用程序的吞吐量和 Web 服务器上的负载之间找到适当的平衡。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-13
    • 2012-07-22
    • 2013-05-13
    • 2020-04-16
    • 2023-03-08
    • 2019-08-04
    • 2019-12-30
    • 2022-01-20
    相关资源
    最近更新 更多