2010-01-19 73 views

回答

6

該隊列沒有實際限制,但池本身不會超過64個等待句柄,即活動的線程總數。

+0

一個錯誤導致我的問題,但基本上問題的答案是這樣的。 – 2010-01-21 15:15:00

+0

謝謝@keith。所以這聽起來像隊列大小的唯一真正的限制是一個通用隊列(或類似的)對象本身的大小。 – matrixugly 2016-01-14 23:45:21

+0

什麼?我有150個線程池線程活動! – Vlad 2016-09-04 19:55:59

4

documentation of ThreadPool

注:在託管線程池中的線程是後臺線程。也就是說,他們的IsBackground屬性是真實的。這意味着ThreadPool線程在所有前臺線程退出後都不會讓應用程序繼續運行。

在處理所有任務之前是否可能退出?

4

這是一個依賴於實現的問題,這個函數的實現隨着時間的推移發生了一些變化。但在.NET 4.0中,由於任務存儲在內存隊列中,因此本質上受系統內存量的限制。通過挖掘反射器中的實現可以看到這一點。

11

如果您需要等待所有要處理的任務,則需要自己處理。 ThreadPool線程都是後臺線程,並且不會讓應用程序保持活動狀態。

這是處理這種情況相對乾淨的方式:

using (var mre = new ManualResetEvent(false)) 
{ 
     int remainingToProcess = workItems.Count(); // Assuming workItems is a collection of "tasks" 
     foreach(var item in workItems) 
     { 
      // Delegate closure (in C# 4 and earlier) below will 
      // capture a reference to 'item', resulting in 
      // the incorrect item sent to ProcessTask each iteration. Use a local copy 
      // of the 'item' variable instead. 
      // C# 5/VS2012 will not require the local here. 
      var localItem = item; 
      ThreadPool.QueueUserWorkItem(delegate 
      { 
       // Replace this with your "work" 
       ProcessTask(localItem); 

       // This will (safely) decrement the remaining count, and allow the main thread to continue when we're done 
       if (Interlocked.Decrement(ref remainingToProcess) == 0) 
         mre.Set(); 
      }); 
     } 
     mre.WaitOne(); 
} 

話雖這麼說,它通常是更好的「集團」你的工作項目,如果你有成千上萬的他們,不要將它們視爲線程池的單獨工作項目。這是管理項目列表的一些開銷,並且由於您無法一次處理22000個項目,所以最好將它們分組爲塊。單個工作項目每個過程50左右可能會幫助您的整體吞吐量相當多...

+0

好主意,但該應用程序正在等待所有線程。分組也是一個非常好的建議。 – 2010-01-21 15:13:29