Task.Factory.StartNew为啥同一次添加10几个线程,超过8个后面添加的线程变开始变慢


勇哥描述一下:

如下面代码,当循环Task.Factory.StartNew到第9个的时候,会发现要隔约1秒才可以添加第9个,后面的第10,11,12,13,14 都要间格较长时间。

如果你把下面代码中的while死循环去掉,则15个线程瞬间添加完成。

这是什么原因呢?

 for (int i = 0; i < 15; i++)
            {
                var t1 = Task.Factory.StartNew(fun);
                taskList.Add(t1);
            }
            
 
        private void fun()
        {
            OutMsg($"id={Thread.CurrentThread.ManagedThreadId}, 启动时间:{DateTime.Now.ToString("hh:mm:ss:ms")}\n");
            Stopwatch sw1 = new Stopwatch();
            sw1.Start();
            while (true)
            {
               
                Thread.Sleep(5);
                if (sw1.ElapsedMilliseconds > 4000)
                {
                    sw1.Stop();
                    OutMsg($"id={Thread.CurrentThread.ManagedThreadId}, 退出时间:{DateTime.Now.ToString("hh:mm:ss:ms")}\n");
                    break;
                }
            }
        }


勇哥直接说答案:


用下面代码测试。

线程池最大允许线程数: 指的是你的cpu最大允许创建的线程总数,超过这个数再创建的就要排队了。

最小可用线程数: 就是你一次最多可以添加的线程数量,它的默认值就是你的cpu数量,如果图2所示。

                           本文的问题就是因为这个最小可用线程数太小,超过8个的线程添加就要排队,可以用ThreadPool.SetMinThreads() 来增加这个最小线程数

可用辅助线程的数目:  当你添加一个线程时,图1所示的“可用辅助线程的数目”就会减1


int data1, data2;
            ThreadPool.GetAvailableThreads(out data1, out data2);
            int data3, data4;
            ThreadPool.GetMinThreads(out data3, out data4);
            int d5, d6;
            ThreadPool.GetMaxThreads(out d5, out d6);


            OutMsg2($"线程池最大允许线程数:{d5}\n最小可用线程数:{data3}\n可用辅助线程的数目 : {data1}\n");

image.png

(图1)


image.png

(图2)



结论:

如下面代码,

此问题通过ThreadPool.SetMinThreads() 把最小线程数由8改为最大就可以了。

   int workerThreadsMin, completionPortThreadsMin;
            ThreadPool.GetMinThreads(out workerThreadsMin, out completionPortThreadsMin);
            int workerThreadsMax, completionPortThreadsMax;
            ThreadPool.GetMaxThreads(out workerThreadsMax, out completionPortThreadsMax);

            // Adjust min threads
            ThreadPool.SetMinThreads(workerThreadsMax, completionPortThreadsMin);

可能有人会问,题目说的是task,最后结论为啥整出个线程池的方法ThreadPool.SetMinThreads() ?

因为Task.Factory.StartNew开的线程默认就是投放到线程池内工作的(当然你也可以指定放到Thread中),因此适用ThreadPool.SetMinThreads()方法。



测试源代码下载:


支付2元或购买VIP会员后,才能查看本内容!立即支付升级会员查询订单


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:
本帖最后由 勇哥,很想停止 于 2023-07-13 08:57:01 编辑

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864