線程池模式與C#中用法

一、線程池模式解析

1. 核心概念

線程池是一種?管理線程生命周期的技術,主要解決以下問題:

  • 減少線程創建/銷毀開銷:復用已存在的線程

  • 控制并發度:避免無限制創建線程導致資源耗盡

  • 任務隊列:有序處理異步請求

2. 工作流程

?

3. .NET 中的實現
  • 內置線程池System.Threading.ThreadPool

  • 關鍵方法

ThreadPool.QueueUserWorkItem(state => { /* 任務邏輯 */ });

4. 線程池組成System.Threading.ThreadPool
組件說明
Worker Threads處理普通任務
I/O Completion Ports處理異步I/O操作
任務隊列存放等待執行的任務

二、基本使用方法

1. 提交任務
// 使用 QueueUserWorkItem
ThreadPool.QueueUserWorkItem(state => 
{Console.WriteLine($"Task executed on thread {Thread.CurrentThread.ManagedThreadId}");// 長時間運行的任務
});// 帶參數的任務
ThreadPool.QueueUserWorkItem(obj => 
{var data = (string)obj;Console.WriteLine($"Processing: {data}");
}, "Hello ThreadPool");

2. 獲取線程池狀態

ThreadPool.GetAvailableThreads(out int workerThreads, out int completionPortThreads);
Console.WriteLine($"可用工作線程: {workerThreads}, I/O線程: {completionPortThreads}");ThreadPool.GetMinThreads(out int minWorker, out int minIO);
ThreadPool.GetMaxThreads(out int maxWorker, out int maxIO);

?

三、高級配置

1. 設置線程數限制
// 設置最小線程數(預熱)
ThreadPool.SetMinThreads(4, 4);// 設置最大線程數(默認值通常足夠)
ThreadPool.SetMaxThreads(16, 16); // 不推薦隨意修改
2. 使用 Task 封裝(現代推薦方式)
Task.Run(() => 
{// 會自動使用ThreadPoolConsole.WriteLine("Running via Task");
});
3. 帶返回值的任務
var result = await Task.Run(() => 
{Thread.Sleep(1000);return 42;
});
Console.WriteLine($"Result: {result}");

四、最佳實踐

1. 適合場景
場景示例
短期任務<1秒完成的任務
I/O密集型文件/網絡操作
并行計算簡單的數據分塊處理
2. 不適合場景
場景問題替代方案
長時間運行阻塞線程池線程new Thread()?或?LongRunning?任務
需要優先級線程池無優先級自定義優先級隊列
精細控制需要線程親和性專用線程
3. 性能調優建議
// 在應用啟動時預熱線程池
ThreadPool.SetMinThreads(Environment.ProcessorCount * 2, Environment.ProcessorCount * 2);// 監控線程池狀態
PerformanceCounter poolCounter = new PerformanceCounter("ThreadPool", "Thread Count", Process.GetCurrentProcess().ProcessName);

五、與 DelegateSpooler 對比

特性ThreadPoolDelegateSpooler
線程管理自動手動控制
任務隊列全局共享獨立實例
優先級不支持可自定義
適用場景通用短期任務需要特殊控制的場景

?

六、完整示例

1. 批量處理任務
using System;
using System.Threading;class Program
{static void Main(){// 設置最小線程數ThreadPool.SetMinThreads(4, 4);// 提交10個任務for (int i = 0; i < 10; i++){int taskId = i;ThreadPool.QueueUserWorkItem(_ => {Console.WriteLine($"Task {taskId} started on thread {Thread.CurrentThread.ManagedThreadId}");Thread.Sleep(1000); // 模擬工作Console.WriteLine($"Task {taskId} completed");});}Console.ReadLine();}
}
2. 異步I/O操作
using System.Net;
using System.IO;ThreadPool.QueueUserWorkItem(_ => 
{var request = WebRequest.Create("https://example.com");using var response = request.GetResponse();using var reader = new StreamReader(response.GetResponseStream());Console.WriteLine(reader.ReadToEnd());
});

七、常見問題解決

1. 線程饑餓

現象:任務長時間排隊不執行
解決

// 增加最小線程數
ThreadPool.SetMinThreads(Environment.ProcessorCount * 2, Environment.ProcessorCount * 2);
2. 異常處理
ThreadPool.QueueUserWorkItem(_ => 
{try{// 可能拋出異常的代碼}catch (Exception ex){Console.WriteLine($"Task failed: {ex}");}
});
3. 取消任務
var cts = new CancellationTokenSource();// 提交可取消任務
Task.Run(() => 
{while (!cts.IsCancellationRequested){// 工作代碼}
}, cts.Token);// 取消所有任務
cts.Cancel();

總結

  • 簡單任務:優先使用?ThreadPool.QueueUserWorkItem

  • 現代開發:推薦使用?Task.Run(內部使用線程池)

  • 復雜場景:考慮自定義線程池(如?DelegateSpooler

  • 關鍵原則:避免阻塞線程池線程,保持任務短小精悍

通過合理使用線程池,可以顯著提升應用程序的并發性能和資源利用率。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/81546.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/81546.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/81546.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

設置IDEA打開新項目使用JDK17

由于最近在學習Spring-AI&#xff0c;所以JDK8已經不適用了&#xff0c;但是每次創建新項目都還是JDK8&#xff0c;每次調來調去很麻煩 把Projects和SDKs都調整為JDK17即可 同時&#xff0c;Maven也要做些更改&#xff0c;主要是添加build標簽 <build><plugins>&…

初識MySQL · 索引

目錄 前言&#xff1a; 重溫磁盤 認識索引 為什么這么做&#xff0c;怎么做 重談page 聚簇索引VS非聚簇索引 回表查詢 索引分類 前言&#xff1a; 前文我們主要是介紹了MySQL的一些基本操作&#xff0c;增刪查改一類的操作都介紹了&#xff0c;并且因為大多數情況下&am…

MySQL——7、復合查詢和表的內外連接

復合查詢和表的內外連接 1、基本查詢回顧2、多表查詢3、自連接4、子查詢4.1、單行子查詢4.2、多行子查詢4.3、多列子查詢4.4、在from子句中使用子查詢4.5、合并查詢 5、表的內連和外連5.1、內連接5.2、外連接5.2.1、左外連接5.2.2、右外連接 1、基本查詢回顧 1.1、查詢工資高于…

MYSQL故障排查和環境優化

一、MySQL故障排查 1. 單實例常見故障 &#xff08;1&#xff09;連接失敗類問題 ERROR 2002 (HY000): Cant connect to MySQL server 原因&#xff1a;MySQL未啟動或端口被防火墻攔截。 解決&#xff1a;啟動MySQL服務&#xff08;systemctl start mysqld&#xff09;或開放…

7GB顯存如何部署bf16精度的DeepSeek-R1 70B大模型?

構建RAG混合開發---PythonAIJavaEEVue.js前端的實踐-CSDN博客 服務容錯治理框架resilience4j&sentinel基礎應用---微服務的限流/熔斷/降級解決方案-CSDN博客 conda管理python環境-CSDN博客 快速搭建對象存儲服務 - Minio&#xff0c;并解決臨時地址暴露ip、短鏈接請求改…

數字圖像處理——圖像壓縮

背景 圖像壓縮是一種減少圖像文件大小的技術&#xff0c;旨在在保持視覺質量的同時降低存儲和傳輸成本。隨著數字圖像的廣泛應用&#xff0c;圖像壓縮在多個領域如互聯網、移動通信、醫學影像和衛星圖像處理中變得至關重要。 技術總覽 當下圖像壓縮JPEG幾乎一統天下&#xff…

抖音視頻怎么去掉抖音號水印

你是不是經常遇到這樣的煩惱&#xff1f;看到喜歡的抖音視頻&#xff0c;想保存下來分享給朋友或二次創作&#xff0c;卻被抖音號水印擋住了畫面&#xff1f;別著急&#xff0c;今天教你幾種超簡單的方法&#xff0c;輕松去除水印&#xff0c;高清無水印視頻一鍵保存&#xff0…

RISC-V 開發板 MUSE Pi Pro PCIE 測試以及 fio 崩潰問題解決

視頻講解&#xff1a; RISC-V 開發板 MUSE Pi Pro PCIE 測試以及 fio 崩潰問題解決 板子上有一個m.2的pcie插槽&#xff0c;k1有三個pcie控制器&#xff0c;pcie0和usb3復用一個phy&#xff0c;所以實際開發板就兩個&#xff0c;測試的話&#xff0c;上一個nvme硬盤&#xff0c…

超級管理員租戶資源初始化與授權管理設計方案

背景說明 在多租戶系統中&#xff0c;資源&#xff08;如功能模塊、系統菜單、服務能力等&#xff09;需按租戶維度進行授權管理。超級管理員在創建新租戶時&#xff0c;需要初始化該租戶的資源授權信息。 兩種可選方案 方案描述方案 A&#xff1a;前端傳入選中的資源列表創…

stm32week16

stm32學習 十一.中斷 4.使用中斷 EXTI的配置步驟&#xff1a; 使能GPIO時鐘設置GPIO輸入模式使能AFIO/SYSCFG時鐘設置EXTI和IO對應關系設置EXTI屏蔽&#xff0c;上/下沿設置NVIC設計中斷服務函數 HAL庫的使用&#xff1a; 使能GPIO時鐘&#xff1a;__HAL_RCC_GPIOx_CLK_EN…

什么是RDMA?

什么是RDMA&#xff1f; RDMA(RemoteDirect Memory Access)技術全稱遠程直接內存訪問&#xff0c;就是為了解決網絡傳輸中服務器端數據處理的延遲而產生的。它將數據直接從一臺計算機的內存傳輸到另一臺計算機&#xff0c;無需雙方操作系統的介入。這允許高吞吐、低延遲的網絡…

golang 安裝gin包、創建路由基本總結

文章目錄 一、安裝gin包和熱加載包二、路由簡單場景總結 一、安裝gin包和熱加載包 首先終端新建一個main.go然后go mod init ‘項目名稱’執行以下命令 安裝gin包 go get -u github.com/gin-gonic/gin終端安裝熱加載包 go get github.com/pilu/fresh終端輸入fresh 運行 &…

【數據結構篇】鏈式結構二叉樹

目錄&#xff1a; 一 二叉鏈的概念與結構&#xff1a; 1.1 概念&#xff1a; 1.2 結構&#xff1a; 二 二叉鏈的實現&#xff1a; 2.1 二叉樹的構建&#xff1a; 2.2 二叉樹的遍歷&#xff1a; 2.2.1 前序遍歷&#xff1a; 2.2.2 中序遍歷&#xff1a; 2.2.3 后序遍歷…

【MySQL】02.數據庫基礎

1. 數據庫的引入 之前存儲數據用文件就可以了&#xff0c;為什么還要弄個數據庫? 文件存儲存在安全性問題&#xff0c;文件不利于數據查詢和管理&#xff0c;文件不利于存儲海量數據&#xff0c;文件在程序中控制不方便。而為了解決上述問題&#xff0c;專家們設計出更加利于…

什么是 Langchain 以及其核心組件

LangChain 官方文檔&#xff1a;LangChain 一、什么是Langchain LangChain 是一個用于構建基于LLM的應用框架&#xff0c;它提供了對 LLM API 的封裝和擴展&#xff0c;使開發者能夠更方便地構建復雜的應用。 個人理解&#xff1a;用類比的方法來說&#xff0c;LangChain類似…

博客系統功能測試

博客系統網址&#xff1a;http://8.137.19.140:9090/blog_list.html 主要測試內容 功能測試、界面測試、性能測試、易用性測試、安全測試、兼容性測試、弱網測試、安裝卸載測試、壓力測試… 測試方法及目的 利用selenium和python編寫測試腳本&#xff0c;對博客系統進行的相關…

項目制作流程

一、使用 CRA 創建項目 npx create-react-app name 二、按照業務規范整理項目目錄 &#xff08;重點src目錄&#xff09; 三、安裝插件 npm install sass -Dnpm install antd --savenpm install react-router-dom 四、配置基礎路由 Router 1. 安裝路由包 react-router-dom …

ngx_http_random_index_module 模塊概述

一、使用場景 隨機內容分發 當同一目錄下存放多份等價內容&#xff08;如多張輪播圖、不同版本靜態頁面等&#xff09;時&#xff0c;可通過隨機索引實現負載均衡或流量分散。A/B 測試 通過目錄請求自動隨機分配用戶到不同測試組&#xff0c;無需后端邏輯參與。動態“首頁”選…

智能權限守護者:基于Python描述符的動態角色控制實現

智能權限守護者:基于Python描述符的動態角色控制實現 引言:當描述符遇見權限管理 在Python的魔法方法體系中,描述符(Descriptor)以其優雅的屬性訪問控制機制著稱。當我們將描述符與RBAC(基于角色的訪問控制)模型結合,就能創造出既靈活又安全的動態權限管理系統。本文…

Linux 的 UDP 網絡編程 -- 回顯服務器,翻譯服務器

目錄 1. 回顯服務器 -- echo server 1.1 相關函數介紹 1.1.1 socket() 1.1.2 bind() 1.1.3 recvfrom() 1.1.4 sendto() 1.1.5 inet_ntoa() 1.1.6 inet_addr() 1.2 Udp 服務端的封裝 -- UdpServer.hpp 1.3 服務端代碼 -- UdpServer.cc 1.4 客戶端代碼 -- UdpClient.…