您可以在线程池中排队的工作项数量是否有限制?

时间:2011-05-09 20:17:20

标签: .net clr queue threadpool

您可以在线程池队列中放置多少项?

 ThreadPool.QueueUserWorkItem(someCallBack);

MSDN没有给出任何限制的指示,如果您可以通过它会发生什么情况(它会暂时停止发布的线程吗?还是会抛出异常?)

举个例子。如果我只排队队列中的100,000个项目怎么办?那会有用吗?

3 个答案:

答案 0 :(得分:2)

您可以使用Threadpool.GetMaxThreads()和Threadpool.SetMaxThreads()来确定/修改池中的最大线程数。

当您对工作项进行排队时,如果可能,它将从池中的空闲线程开始执行,或者如果所有线程都忙,它将等待线程变为可用,然后再开始执行。如果排队并且没有可用的线程,则不会收到错误。

答案 1 :(得分:2)

对排队项目的数量没有理论上的限制,它应该继续向队列添加回调,直到您耗尽资源为止。

但是,为什么你想首先添加那么多?如果您要添加很多项目,那么它们很可能非常短暂,您最好为您的任务找出更好的分区方案。

答案 2 :(得分:0)

我认为唯一的限制是队列中最多可以包含UInt32.MaxValue。如果你使用32位CLR,你会事先耗尽内存,所以你永远不会达到这个限制。

我想在64位CLR上你理论上可以达到这个限制,但我认为你需要大约850GB的内存来测试它。在开始耗尽内存之前(在安装了8GB RAM的计算机上),我使用6-7GB的工作集获得了大约40,000,000个排队项目。

我不知道如果你达到极限会发生什么。从快速查看带有反射器的mscorlib,它甚至可能不会抛出异常,而只是溢出不可预测的结果。

如果你的机器有大约1TB的内存,这里有一个小测试片段,试着亲自看看会发生什么:)

class Program
    {
        static void Main(string[] args)
        {
            for (long i = 0; ; ++i)
            {
                bool succeeded = ThreadPool.QueueUserWorkItem(SleepCallBack);
                if ((i % 1000) == 0)
                {
                    Console.WriteLine(i);
                }
                if (!succeeded) break;
            }
            Console.Read();
        }

        private static void SleepCallBack(object stateInfo)
        {
            Thread.Sleep(System.Threading.Timeout.Infinite);
        }