C# 为什么ThreadPool.QueueUserWorkItem在线程数达到MinThreads限制后变慢? 类程序 { 静态void DoIt(字符串名称) { WriteLine($“{DateTime.Now},线程{name}已启动”); 睡眠(50000); WriteLine($“{DateTime.Now},线程{name}done”); } 静态void Main() { //SetMinThreads(100100); 对于(int i=0;i { 字符串名称=value.ToString(); DoIt(姓名); }); } Console.ReadKey(); } }

C# 为什么ThreadPool.QueueUserWorkItem在线程数达到MinThreads限制后变慢? 类程序 { 静态void DoIt(字符串名称) { WriteLine($“{DateTime.Now},线程{name}已启动”); 睡眠(50000); WriteLine($“{DateTime.Now},线程{name}done”); } 静态void Main() { //SetMinThreads(100100); 对于(int i=0;i { 字符串名称=value.ToString(); DoIt(姓名); }); } Console.ReadKey(); } },c#,.net,multithreading,task,threadpool,C#,.net,Multithreading,Task,Threadpool,计划的结果: 2021/4/26 11:26:23,线程2已启动 2021/4/26 11:26:23,Thread0已启动 2021/4/26 11:26:23,Thread1已启动 2021/4/26 11:26:23,Thread3启动 2021/4/26 11:26:24,Thread4启动 2021/4/26 11:26:25,线程5已启动 2021/4/26 11:26:26,线程6已启动 2021/4/26 11:26:27,线程7已启动 2021/4/26 11:26:28,T

计划的结果:

2021/4/26 11:26:23,线程2已启动
2021/4/26 11:26:23,Thread0已启动
2021/4/26 11:26:23,Thread1已启动
2021/4/26 11:26:23,Thread3启动
2021/4/26 11:26:24,Thread4启动
2021/4/26 11:26:25,线程5已启动
2021/4/26 11:26:26,线程6已启动
2021/4/26 11:26:27,线程7已启动
2021/4/26 11:26:28,Thread8启动
2021/4/26 11:26:29,线程9开始

同时启动100个线程。前4个线程非常快。后一个线程每秒启动一个线程,直到一些工作线程完成

  • 为什么前4个线程很快? 我电脑的cpu核心是4个。如果程序在8或32核计算机中运行,则前8或32个线程速度较快,其他线程速度较慢
  • 如果将minthreads设置为100,则所有100个线程都会快速启动
  • 如果我不设置线程,为什么后面的线程启动得那么慢?

    • NET线程池将提供线程,直到达到最小值(Threadpool.GetMinThreads)为止,不会有任何延迟
    • 在此之后,线程池可以等待任务完成(排队)或创建新线程(直到到达threadpool.GetMaxThreads)
    • 线程池何时创建新线程的实际算法没有被记录下来,因为它一直在发展。但这取决于它运行的硬件和它计算的一系列统计数据
    • 通过将SetMinThreads设置为100,您实际上是在告诉.NET线程池提供100个线程,而不会提出任何问题。这就是线程启动速度快的原因
    • 将MinThreads设置为高值有其自身的缺点…(您应该看到内存使用量的增加,因为每个线程都需要有自己的内存用于调用堆栈等,并且随着线程数量的增加,处理器将花费更多的时间来进行上下文切换,而不是实际处理)
    • minthreads的默认值取决于内核数和.net framework版本。这就是为什么当您移动到不同的硬件时,行为会发生变化

    GetMaxThreads返回的值是多少?我们打算说的基本相同。将为添加一个链接,以说明线程池可能是复杂的,并且可以解释如何处理最小/最大线程数。
    class Program
        {
            static void DoIt(string name)
            {            
                Console.WriteLine($"{DateTime.Now}, Thread{name} started");
                Thread.Sleep(50000);
                Console.WriteLine($"{DateTime.Now}, Thread{name} done");
            }
    
            static void Main()
            {
                //ThreadPool.SetMinThreads(100, 100);
    
                for (int i = 0; i < 100; i++)
                {
                    int value = i;
                    ThreadPool.QueueUserWorkItem((s) =>
                    {
                        string name = value.ToString();
                        DoIt(name);
                    });
                }
    
                Console.ReadKey();
            }
        }