最近学习多线程 遇到点问题
先看一段ConsoleApp程序吧 
        static void Main(string[] args)
        {
            ThreadPool.SetMinThreads(100, 100);
            ThreadPool.SetMaxThreads(100, 100);
            Console.WriteLine("start...");
            DateTime now = DateTime.Now;
            for (int i = 0; i < 50; i++)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(CallBack), null);
            }            Console.ReadLine();
        }        static void CallBack(object o)
        {
            Thread.Sleep(5000);
            int a, b;
            ThreadPool.GetAvailableThreads(out a, out b);
            string message = string.Format("CurrentThreadId is {0}\n  " +
                  "CompletionPortThreads is :{1}", a.ToString(), b.ToString());
            Console.WriteLine(message);
        }
这个程序很简单  就是先设置线程池最大最小都为100,然后循环50次线程  每个线程中的处理都睡眠5秒,由于提前设置了线程池最小线程是100, 所以程序结果所花费的时间差不多是5秒左右。到这里我是明白的,下面测试Asp.net程序中的ashx (注意 这里ashx不是异步的Handler)
首先和上面一样在Global。asax中设置线程池最大最小都为100.
我在一个ashx中   同样写入ThreadPool.GetAvailableThreads来观察线程池中工作线程和I/O线程的使用情况,先测了一下,访问一次ashx 看输出结果线程池的工作线程少了几个  所以我认为访问ashx的时候也是调用线程池中的工作线程的。
那么我就满心欢喜的直接在测试ashx中的ProcessRequest方法里也写下睡眠5秒的处理
        public void ProcessRequest(HttpContext context)
        {
            System.Threading.Thread.Sleep(5000);
            int a, b;
            ThreadPool.GetAvailableThreads(out a, out b);
            string message = string.Format("WorkerThreads is {0}\n  " +
                  "CompletionPortThreads is :{1}", a.ToString(), b.ToString());            Debug.WriteLine(message);
        }
既然都已经设置线程池最小为100了,那如果同时50次访问,应该和上面ConsoleApp程序一样是5秒左右。
可是我用测试软件模拟了50次  结果是第一次是花了18秒 第二次趋于稳定是15秒左右 以后都是.
这是为什么呢???ConsoleApp程序的线程池  和 Asp.net程序的线程池难道有区别?? 
先不考虑用异步Handler 大家先帮我看看到底哪里理解错了 那些多余花费的时间是什么?
请教大虾们哈

解决方案 »

  1.   

    第一个程序里的 有个地方写错了  不是CurrentThreadId 是WorkerThreads 
    string message = string.Format(CurrentThreadId is {0}\n  " +
                      "CompletionPortThreads is :{1}", a.ToString(), b.ToString());
    改成
    string message = string.Format(WorkerThreads is {0}\n  " +
                      "CompletionPortThreads is :{1}", a.ToString(), b.ToString());
      

  2.   

    虽然没有研究过,不过感觉,这是http和本机winform程序的不同吧,不是代码问题,两种程序依托的运行环境不一样
      

  3.   

    系统的开销什么的吧。
    IIS起码自己就那么大。lz可以把sleep加大5秒。如果后来趋近于稳定在20秒,也就是线性增长,那可以确定是系统带来的开销了。
      

  4.   

    进一步测试后  发现同时访问ashx 不是一次性就调用线程池50个线程  而是有间隔的  就感觉有点像在创建线程所在消耗的时间  
    但是我已经设置线程池最小为100了 然后我有测试了下 在ashx中加入了 ThreadPool.GetMinThreads 来查验是不是100
    结果的确是100  也就是那个间隔并不是创建线程所消耗的时间  而且那个间隔很诡异  间隔时间不是均匀的 
    而且那个间隔不是一个线程一个线程之间的间隔  而是10几个线程之间 
    所以更加否定了是创建线程消耗的时间  
      

  5.   


    单用线程之间的间隔,我估计不好测吧。
    起码的ashx什么的装载也需要时间。如果是我,我只看时间是否线性增长。
      

  6.   


    单用线程之间的间隔,我估计不好测吧。
    起码的ashx什么的装载也需要时间。如果是我,我只看时间是否线性增长。
      

  7.   

    考虑网络上的延迟吧,这里用的TCP/IP协议,因此受到了半开连接数10的限制,不能很快建立50个连接,网络响应总有延迟的。