我将最大线程数设置为10。然后使用ThreadPool.QueueUserWorkItem添加了22000个任务。 运行程序后很可能并没有完成所有22000个任务。是否有任务数量限制可以排队等待可用线程?
我将最大线程数设置为10。然后使用ThreadPool.QueueUserWorkItem添加了22000个任务。 运行程序后很可能并没有完成所有22000个任务。是否有任务数量限制可以排队等待可用线程?
如果您需要等待所有任务处理完成,您需要自己处理。线程池线程都是后台线程,不会保持应用程序的活动状态。
以下是一种比较简洁的处理方法:
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个左右可能会极大地提高你的整体吞吐量...
从ThreadPool文档中:
注意: 托管线程池中的线程是后台线程。也就是说,它们的IsBackground属性是true。这意味着,在所有前台线程退出后,ThreadPool线程将不会使应用程序继续运行。
你是否可能在所有任务被处理之前退出了?