ThreadPool.QueueUserWorkItem中的最大排队元素

我将最大线程设置为10.然后我使用ThreadPool.QueueUserWorkItem添加了22000任务。 运行该程序后很可能并非所有22000任务都已完成。 有多少任务可以排队等待可用线程?

队列没有实际限制,但池本身不会超过64个等待句柄,即总线程活动。

如果您需要等待处理所有任务,则需要自己处理。 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左右可能会帮助您的整体吞吐量相当多…

这是一个依赖于实现的问题,随着时间的推移,这个函数的实现已经发生了一些变化。 但是在.Net 4.0中,由于任务存储在内存队列中,因此您基本上受限于系统中的内存量。 您可以通过挖掘reflection器中的实现来看到这一点。

从ThreadPool的文档 :

注意:托管线程池中的线程是后台线程。 也就是说,它们的IsBackground属性是真的。 这意味着在所有前台线程退出后,ThreadPool线程不会保持应用程序运行。

您是否有可能在处理完所有任务之前退出?