2010-01-19 52 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