2013-08-01 235 views
1

嗨,我让自己与Task.Factory.StartNew绑在一起。就像我认为我知道有人建议我写下面的代码一样;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个任务排队运行,而不是正在运行。那么如何确定运行/可运行任务的数量?

+0

Task.Factory会立即执行队列中的每个任务,或者在调度程序找到可用线程时执行。此外,使用StartNew方法时,您需要传递取消令牌,以避免由GC导致的任务意外终止。我不知道如何确定运行/可运行任务的数量。 –

+0

另外我忘了提及,任务池不会锁定任何东西,这就是为什么有一个任务调度器。 –

+0

您是否想知道当前正在运行的任务数量或任务是否尚未完成? – Linky

回答

0

我知道这是相当长的一段时间后,您的文章,但我希望这可能会帮助面临您的具体挑战的人。您最后的评论指出'DeliverMessage'方法正在发出HTTP请求。

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

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