勇哥描述一下:
如下面代码,当循环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");
(图1)
(图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()方法。
测试源代码下载:

