2013-08-01 233 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服務器上的負載之間找到適當的平衡點,您必須使用此設置的不同值。