『线程池』在.NET中如何优雅地调优ThreadPool
创始人
2025-05-30 03:58:19
0

请添加图片描述
📣读完这篇文章里你能收获到

  • 了解线程池不足的常见现象
  • 解析引起线程池不足的原因
  • 根据不同的需求场景提出不同的优化措施
  • 感谢点赞+收藏,避免下次找不到~

请添加图片描述

文章目录

  • 一、ThreadPool 资源不足会有引起哪些现象
  • 二、引起 ThreadPool 资源不足的常见原因
  • 三、调优 ThreadPool 的措施
    • 1. 使用异步编程模型
    • 2. 使用 Task.Factory.StartNew
    • 3. 长时间运行的任务处理
    • 4. 合理设置线程池参数
  • 四、.NET中如何合理设置线程池参数
    • 1. 线程池最大线程数
    • 2. 线程池最小线程数
    • 3. 线程池队列长度
    • 4. 线程池工作线程优先级

请添加图片描述

一、ThreadPool 资源不足会有引起哪些现象

  1. 任务执行时间变长:由于Task.Run 和 ThreadPool.QueueUserWorkItem 都是将任务提交给线程池执行,而线程池中的工作者线程不足,因此需要等待其他任务执行完成后才能得到执行,会导致整体的任务执行时间会变长。
  2. 程序崩溃:如果线程池中没有可用的工作者线程,新的任务将无法得到执行,从而导致程序崩溃或出现异常。
  3. 内存泄漏:如果使用了大量的异步任务,而线程池中的工作者线程数不足,会导致这些任务一直在等待线程池资源,从而占用大量的内存资源,引发内存泄漏。
  4. 服务器性能下降:如果是 Web 应用程序,当线程池资源不足时,可能会导致服务器的性能下降,响应时间变长,甚至无法响应客户端请求。

请添加图片描述

二、引起 ThreadPool 资源不足的常见原因

  1. 阻塞操作:如果您的代码中存在阻塞操作(例如 I/O 操作),并且这些操作使用了同步方式,这可能会导致线程池中的线程被阻塞。当线程被阻塞时,它不能被用于执行其他任务,从而导致线程池资源不足。
  2. 长时间运行的任务:如果您的代码中存在长时间运行的任务(例如计算密集型操作),这可能会导致线程池中的线程被占用。当线程被占用时,它不能被用于执行其他任务,从而导致线程池资源不足。
  3. 不恰当的线程使用:如果您的代码中创建了大量的线程(例如使用 Thread 类),而不是使用线程池,这可能会导致线程池资源不足。因为线程池的目的是重复使用线程来执行任务,如果您自己创建线程,则会降低线程池的效率。
  4. 线程泄漏:如果您的代码中存在线程泄漏(例如线程未正确释放),这可能会导致线程池资源不足。因为线程池中的线程是有限的,如果您的代码中存在泄漏的线程,则这些线程将一直占用线程池资源,直到应用程序退出。

请添加图片描述

三、调优 ThreadPool 的措施

1. 使用异步编程模型

  • 使用 async/await:使用异步编程模型,可以避免线程被阻塞,从而释放线程池资源。
//【避免】会阻止线程,这是导致 ThreadPool 资源不足的最常见原因
Customer c = PretendQueryCustomerFromDbAsync("Dana").Result;//【建议】使用 await 可让当前线程在数据库查询过程中为其他工作项提供服务
Customer c = await PretendQueryCustomerFromDbAsync("Dana");

2. 使用 Task.Factory.StartNew

  • 使用 Task.Factory.StartNew 方法:可以使用 Task.Factory.StartNew 方法,手动创建一个新的任务,而不是使用线程池中的工作者线程执行任务,以避免线程池资源不足导致任务无法执行的情况
Task.Factory.StartNew(() => {// 执行任务
});

3. 长时间运行的任务处理

  • 尽可能避免长时间运行的任务:尽可能使用短时间运行的任务,避免使用计算密集型操作,如需长时间运行任务(比如与应用生命周期相同),可以通过在调用 Task.Factory.StartNew 方法时传入 TaskCreationOptions.LongRunning 参数,可以通知 TaskScheduler 创建一个新线程来执行该任务。这种方式可以避免使用线程池线程来执行长时间运行的任务,从而避免线程池资源不足的情况。
Task.Factory.StartNew(() => {// 执行长时间运行的任务
}, TaskCreationOptions.LongRunning);

4. 合理设置线程池参数

  • 参考以下

请添加图片描述

四、.NET中如何合理设置线程池参数

1. 线程池最大线程数

  • 应根据应用程序的负载情况来设置,以确保最大限度地利用计算资源。在设置最大线程数时,应该考虑到应用程序中存在的所有线程和其他系统资源的使用情况。
//将线程池的最大工作者线程数设置为当前最大线程数的两倍
int workerThreads, completionPortThreads;
ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
ThreadPool.SetMaxThreads(workerThreads * 2, completionPortThreads);

2. 线程池最小线程数

  • 应根据应用程序的负载情况来设置,以确保始终有足够的线程可用于执行任务。一般情况下,线程池最小线程数应该设置为 0,以允许线程池动态调整线程数。
//将线程池的最小工作者线程数和 I/O 完成端口线程数都设置为 10。
ThreadPool.SetMinThreads(10, 10);

3. 线程池队列长度

  • 应根据应用程序的负载情况来设置。队列长度应该设置得足够大,以容纳瞬时的任务突发,并允许线程池动态调整队列长度。
//将线程池的队列长度设置为 1000
ThreadPool.SetMaxQueuedWorkItems(1000);

4. 线程池工作线程优先级

  • 应根据应用程序的性能要求和响应时间要求来设置。如果应用程序需要高性能,可以将线程池工作者线程的优先级设置为 ThreadPriority.AboveNormal 或 ThreadPriority.Highest。
//将当前线程(工作者线程)的优先级设置为 ThreadPriority.Highest。
Thread.CurrentThread.Priority = ThreadPriority.Highest;

相关内容

热门资讯

贵阳最新学区划分,最新或202... 贵阳公办小学招生范围按照义务教育免试就近入学原则,市区公办小学实行依街道划片招生。本文为您介绍贵阳小...
遵义最新学区划分,最新或202... 遵义公办小学招生范围按照义务教育免试就近入学原则,市区公办小学实行依街道划片招生。本文为您介绍遵义小...
安顺最新学区划分,最新或202... 安顺公办小学招生范围按照义务教育免试就近入学原则,市区公办小学实行依街道划片招生。本文为您介绍安顺小...
六盘水最新学区划分,最新或20... 百年教育网小编为您整理了关于六盘水市幼升小学区划分详情的相关信息,希望对您有帮助,想了解更多请继续关...
遍历二叉树线索二叉树 遍历二叉树 遍历定义 顺着某一条搜索路径寻访二叉树中的每一个结点,使得每个节点均被依次...
springboot简介和项目... Java知识点总结:想看的可以从这里进入 目录SpringBoot1、简介和原理1....
最新或2023(历届)嘉祥教育... 信息时报讯 面临中考,初三学生陈黎的父母十分发愁。一是孩子成绩并不拔尖,另外,父母虽然有心让儿子出...
“牛孩儿”“每天一题”助你提升... “小升初”的战鼓越擂越响,你准备好了吗?不要着急,自4月29日起,中原网教育频道官方微信“中原教育”...
这是一封发给西安小升初家长的邀... 秦学·伊顿交大校区4月9日晚上举办的小升初讲座圆满结束了,回顾讲座现场的瞬间,小编有一些小小的感动。...
四大法宝护航“528冲刺班”巨... 又是一个四月,春风扑面,鲜花盛开。又是一届小考,竞争激烈,埋头伏案。又是一轮冲刺,全力以赴,舍我其谁...
小升初数学面谈题型归纳 小升初... 数学在小升初择校中的重要性可以说是毋庸置疑的。很多一线名校例如二中应元、六中珠江、广大附等都对数学情...
vue2+3 pinia v... 1. 为什么要学习vue1.官网https://v3.cn.vuejs.org/guide/migr...
防雷设计、防雷检测为什么选同为... 随着现代科技的不断发展,电子设备得到广泛应用,而雷电等自然灾害也越来越频...
最新或2023(历届)快乐的下...  今天下午,我去了隋唐遗址。那里好美丽;有小河;有草地,小河里有鱼,有虾。  我先说河,有的河水清澈...
最新或2023(历届)6年级数...  篇一  今天,妈妈给我出了一道题,题目是这样的:“一头牛可换6头猪,2头猪可换10只羊,三只羊可换...
本次小升初直升考试试卷分析这就... 还记得前几天预告的小升初直升考试吗?这次的考试对于小学六年级的孩子们来说,是非常重要的。家长朋友们也...
西安小升初528预录来了! 西... 相信大家这几天除了被各种各样的学校参观弄得有点晕,到底这参观是几个意思呢!是有暗示还是没暗示,其实这...
最新或2023(历届)认真积极...   今天妈妈带我去学英语,上课我认真听盘,积极的举手回答问题,下课后妈妈表扬了我,我很高兴。回到家我...
【js】多分支语句练习(2) 个人名片: 😊作者简介:一名大一在校生,w...
Git 的 Cherry-Pi... 1、什么是 Cherry-Pickcherry-pick 是 Git 版本控制工具中的一个命令&#x...