您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > .NET

NET中如何优雅地调优ThreadPool

时间:2023-05-21 14:08:34  来源:今日头条  作者:中年农码工

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

任务执行时间变长:由于Task.Run 和
ThreadPool.QueueUserWorkItem 都是将任务提交给线程池执行,当线程池中的工作线程不足时,需要等待其他任务执行完成后才能得到执行,因此会导致整体的任务执行时间会变长。

程序崩溃:如果线程池中没有可用的工作线程,新的任务将无法得到执行,从而导致程序崩溃或出现异常。

内存泄漏:如果使用了大量的异步任务,而线程池中的工作线程数不足,会导致这些任务一直在等待线程池资源,从而占用大量的内存资源,引发内存泄漏。

服务器性能下降:如果是 Web 应用程序,当线程池资源不足时,可能会导致服务器的性能下降,响应时间变长,甚至无法响应客户端请求。

二、导致 ThreadPool 资源不足的常见原因

阻塞操作:如果您的代码中存在阻塞操作(例如 I/O 操作),并且这些操作使用了同步方式,这可能会导致线程池中的线程被阻塞。当线程被阻塞时,它不能被用于执行其他任务,从而导致线程池资源不足。

长时间运行的任务:如果您的代码中存在长时间运行的任务(例如计算密集型操作),这可能会导致线程池中的线程被占用。当线程被占用时,它不能被用于执行其他任务,从而导致线程池资源不足。

不恰当的线程使用:如果您的代码中创建了大量的线程(例如使用 Thread 类),而不是使用线程池,这可能会导致线程池资源不足。因为线程池的目的是重复使用线程来执行任务,如果您自己创建线程,则会降低线程池的效率。

线程泄漏:如果您的代码中存在线程泄漏(例如线程未正确释放),这可能会导致线程池资源不足。因为线程池中的线程是有限的,如果您的代码中存在泄漏的线程,则这些线程将一直占用线程池资源,直到应用程序退出。

三、调优 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;



Tags:ThreadPool   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
程序员必会之最详细的ThreadPoolExecutor 线程池七大参数含义
线程池的 7 大参数整理。public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadF...【详细内容】
2023-10-12  Search: ThreadPool  点击:(317)  评论:(0)  加入收藏
一文搞懂ThreadPoolExecutor原理
前言都说经典的就是好的,这句话放在Java的ThreadPoolExecutor上那是一点都没错,像现在数据库连接的池化实现,或者像Tomcat这种WEB服务器的线程管理,处处都有着ThreadPoolExecut...【详细内容】
2023-06-13  Search: ThreadPool  点击:(352)  评论:(0)  加入收藏
SpringBoot用线程池ThreadPoolExecutor处理百万级数据
一、背景: 使用JDK线程池ThreadPoolExecutor多线程异步执行批量插入、更新等操作方法,提高百万级数据插入效率。二、具体细节: 2.1、创建自适应机器本身线程数量的线程池/...【详细内容】
2023-06-03  Search: ThreadPool  点击:(96)  评论:(0)  加入收藏
NET中如何优雅地调优ThreadPool
一、ThreadPool 资源不足会有引起哪些现象任务执行时间变长:由于Task.Run 和 ThreadPool.QueueUserWorkItem 都是将任务提交给线程池执行,当线程池中的工作线程不足时,需要等待...【详细内容】
2023-05-21  Search: ThreadPool  点击:(220)  评论:(0)  加入收藏
ScheduledThreadPoolExecutor踩过最痛的坑
概述最近项目上反馈某个重要的定时任务突然不执行了,很头疼,开发环境和测试环境都没有出现过这个问题。定时任务采用的是 ScheduledThreadPoolExecutor,后来一看代码发现踩了一...【详细内容】
2022-10-21  Search: ThreadPool  点击:(366)  评论:(0)  加入收藏
什么是线程池?线程池ThreadPoolExecutor使用及其原理又是什么?
线程池,顾名思义,用来存放线程的一个容器先了解一下线程的生命周期 我们为什么要用线程池?技术的发展无非就是需求推动的,而技术领域的需求大部分都是快!再快!更快!那么线程池出现...【详细内容】
2020-08-03  Search: ThreadPool  点击:(416)  评论:(0)  加入收藏
Java 线程池 ThreadPoolExecutor 八种拒绝策略浅析
前言谈到 Java 的线程池最熟悉的莫过于 ExecutorService 接口了,jdk1.5 新增的 java.util.concurrent 包下的这个 api,大大的简化了多线程代码的开发。而不论你用 FixedThread...【详细内容】
2019-08-29  Search: ThreadPool  点击:(889)  评论:(0)  加入收藏
▌简易百科推荐
.Net开发中十种常见的内存错误以及相应的解决方案
在.Net开发中,为内存管理方面提供了许多便利,但仍然存在一些常见的错误和陷阱。这些错误可能导致内存泄漏、性能下降、异常抛出等问题,严重影响应用程序的稳定性和性能。在软件...【详细内容】
2024-03-26  小乖兽技术  今日头条  Tags:.Net   点击:(12)  评论:(0)  加入收藏
.NET配置文件大揭秘:轻松读取JSON、XML、INI和环境变量
概述:.NET中的IConfiguration接口提供了一种多源读取配置信息的灵活机制,包括JSON、XML、INI文件和环境变量。通过示例,清晰演示了从这些不同源中读取配置的方法,使配置获取变得...【详细内容】
2023-12-28  架构师老卢  今日头条  Tags:.NET   点击:(92)  评论:(0)  加入收藏
.Net开发都应当掌握的泛型基础知识集合
在C#编程语言中,泛型是一项非常强大和重要的功能。它允许我们编写更加灵活和通用的代码,同时提高代码的可重用性和性能。本文将介绍C#泛型的一些关键知识点,帮助读者理解和应用...【详细内容】
2023-12-25  小乖兽技术  今日头条  Tags:.Net   点击:(123)  评论:(0)  加入收藏
作为 .NET 开发人员,我为什么开始使用 Python?
作者 | Alex Maher编译 | 小欧作为一名 .NET 开发人员,很长一段时间以来,我一直关注 C# 和 .NET 的出色工具和功能。但我最近开始使用 Python,感觉非常棒。这里申明一点,这篇文...【详细内容】
2023-12-25    51CTO  Tags:.NET   点击:(142)  评论:(0)  加入收藏
.NET Core 3.1 升级到 .NET 8,看看都有哪些变化
.NET Core 3.1 已经用了很长一段时间,其实在 2022 年的年底微软已经不提供支持了,后面的一个 LTS 版本 .NET 6 也会在 2024 年 11 月终止支持,所以直接升级到 .NET 8 是最好的...【详细内容】
2023-12-08  不止dotNET  微信公众号  Tags:.NET   点击:(191)  评论:(0)  加入收藏
.NET Core的中间件来对Web API进行流量限制实现方法
在.NET Core中,我们可以使用ASP.NET Core的中间件来对Web API进行流量限制。ASP.NET Core提供了一个名为RateLimit的开源库,可以方便地实现流量限制功能。下面将详细介绍如何...【详细内容】
2023-12-06  架构师老卢  今日头条  Tags:.NET   点击:(176)  评论:(0)  加入收藏
微软官方出品微服务架构:十个.Net开源项目
1、一个高性能类型安全的.NET枚举实用开源库Enums.NET是一个.NET枚举实用程序库,专注于为枚举提供丰富的操作方法。它支持.NET Framework和.Net Core。它主要优点表现在类型...【详细内容】
2023-12-06  编程乐趣  今日头条  Tags:.Net   点击:(131)  评论:(0)  加入收藏
.NET开源的处理分布式事务的解决方案
前言在分布式系统中,由于各个系统服务之间的独立性和网络通信的不确定性,要确保跨系统的事务操作的最终一致性是一项重大的挑战。今天给大家推荐一个.NET开源的处理分布式事务...【详细内容】
2023-11-30  追逐时光者  微信公众号  Tags:.NET   点击:(173)  评论:(0)  加入收藏
深入 .NET 异步编程:Task 与 ValueTask 的区别与选择
在 .NET 中,Task 和 ValueTask 都是用于表示异步操作的类型,但它们有一些重要的区别。TaskTask 是最常见的表示异步操作的类型。它通常用于表示耗时的、异步的操作,比如从文件...【详细内容】
2023-11-26  架构师老卢  微信公众号  Tags: .NET   点击:(189)  评论:(0)  加入收藏
.NET字符串存储:解析常量与动态字符串,深入了解内存机制
在 .NET 中,字符串是不可变的,这意味着一旦创建,字符串的内容就不能被修改。字符串在内存中以不同的方式存储,具体取决于它是常量字符串还是动态创建的字符串。常量字符串常量字...【详细内容】
2023-11-25  架构师老卢  微信公众号  Tags:.NET   点击:(193)  评论:(0)  加入收藏
站内最新
站内热门
站内头条