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