news 2026/6/15 0:17:28

C#高级:使用ConcurrentQueue做一个简易进程内通信的消息队列

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C#高级:使用ConcurrentQueue做一个简易进程内通信的消息队列

文章目录

  • 一、简介
  • 二、使用场景
  • 三、好处
  • 四、代码
  • 总结

一、简介

使用ConcurrentQueue实现线程安全的进程内消息队列,支持多生产者/消费者模式。

二、使用场景

多线程间数据交换、异步任务处理、日志缓冲等需要线程安全队列的场景。

三、好处

  • 线程安全:内置锁机制,无需额外同步
  • 高性能:无锁设计减少竞争
  • 易用性强:实例绑定Key,简化队列管理

四、代码

usingSystem;usingSystem.Collections.Concurrent;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Threading;usingSystem.Threading.Tasks;/// <summary>/// 简易队列管理器(实例绑定唯一Key,无需重复传参)/// </summary>/// <typeparam name="T">队列元素类型</typeparam>publicclassEasyQueue<T>:IDisposable{// 静态字典:全局管理所有Key对应的队列(保证Key唯一)privatestaticreadonlyConcurrentDictionary<string,ConcurrentQueue<T>>_globalQueueDict=new();// 实例专属Key(创建实例时指定,后续操作无需传参)publicstringQueueKey{get;}// 实例绑定的队列(避免每次从全局字典获取)privateConcurrentQueue<T>_boundQueue;/// <summary>/// 构造函数:注册Key并绑定专属队列(核心优化点)/// </summary>/// <param name="queueKey">队列唯一标识(注册Key)</param>/// <exception cref="ArgumentNullException">Key为空时抛出</exception>publicEasyQueue(stringqueueKey){if(string.IsNullOrWhiteSpace(queueKey))thrownewArgumentNullException(nameof(queueKey),"队列Key不能为空或空白");QueueKey=queueKey;// 注册Key:不存在则创建新队列,存在则绑定已有队列(线程安全)_boundQueue=_globalQueueDict.GetOrAdd(queueKey,_=>newConcurrentQueue<T>());}#region核心方法(无需传Key,直接操作实例绑定的队列)/// <summary>/// 单个元素入队(实例方法,无需传Key)/// </summary>/// <param name="item">要入队的元素</param>publicvoidEnqueue(Titem){_boundQueue.Enqueue(item);}/// <summary>/// 批量元素入队(实例方法,无需传Key)/// </summary>/// <param name="items">要入队的元素列表</param>/// <exception cref="ArgumentNullException">列表为空时抛出</exception>publicvoidEnqueue(List<T>items){if(items==null||items.Count==0)thrownewArgumentNullException(nameof(items),"入队元素列表不能为空或空列表");foreach(variteminitems){_boundQueue.Enqueue(item);}}/// <summary>/// 出队(实例方法,无需传Key)/// </summary>/// <param name="item">出队的元素(队列为空时返回default(T))</param>/// <returns>是否出队成功(true=成功,false=队列为空)</returns>publicboolDequeue(outTitem){return_boundQueue.TryDequeue(outitem);}/// <summary>/// 查询队列所有元素(实例方法,无需传Key)/// </summary>/// <returns>队列元素列表(队列为空返回空List)</returns>publicList<T>GetQueueItems(){return_boundQueue.ToList();}#endregion#region扩展实用方法(实例级,无需传Key)/// <summary>/// 判断当前实例绑定的队列是否为空/// </summary>publicboolIsEmpty=>_boundQueue.IsEmpty;/// <summary>/// 获取当前队列的元素数量/// </summary>publicintCount=>_boundQueue.Count;/// <summary>/// 清空当前队列/// </summary>publicvoidClear(){while(_boundQueue.TryDequeue(out_)){}}/// <summary>/// 静态方法:移除全局字典中的指定Key(注销队列)/// </summary>/// <param name="queueKey">要注销的Key</param>/// <returns>是否注销成功</returns>publicstaticboolUnregisterQueue(stringqueueKey){if(string.IsNullOrWhiteSpace(queueKey))thrownewArgumentNullException(nameof(queueKey));return_globalQueueDict.TryRemove(queueKey,out_);}/// <summary>/// 静态方法:查询全局已注册的所有队列Key/// </summary>/// <returns>所有Key的列表</returns>publicstaticList<string>GetAllRegisteredKeys(){return_globalQueueDict.Keys.ToList();}#endregion#region资源释放privatebool_disposed=false;protectedvirtualvoidDispose(booldisposing){if(!_disposed){if(disposing){// 释放实例时清空绑定的队列(可选,根据业务需求调整)Clear();}_disposed=true;}}publicvoidDispose(){Dispose(true);GC.SuppressFinalize(this);}#endregion}classProgram{staticvoidMain(string[]args){// 定义队列KeyconststringtestKey="MultiThreadQueue";// ========== 线程1:生产数据(入队) ==========TaskproduceTask=Task.Run(()=>{// 创建生产端实例(绑定testKey)varproducerQueue=newEasyQueue<int>(testKey);for(inti=1;i<=100;i++){producerQueue.Enqueue(i);Console.WriteLine($"【生产线程】入队:{i}");Thread.Sleep(1000);// 模拟生产耗时}Console.WriteLine("【生产线程】生产完成!");});// ========== 线程2:消费数据(出队) ==========TaskconsumeTask=Task.Run(()=>{// 创建消费端实例(绑定同一个testKey)varconsumerQueue=newEasyQueue<int>(testKey);intconsumeCount=0;// 循环消费,直到生产完成且队列为空while(!produceTask.IsCompleted||!consumerQueue.IsEmpty){if(consumerQueue.Dequeue(outintitem)){consumeCount++;Console.WriteLine($"【消费线程】出队:{item}");}else{Thread.Sleep(5);// 队列为空时短暂等待,避免空轮询}}Console.WriteLine($"【消费线程】消费完成!共消费{consumeCount}个元素");});// 等待所有线程完成Task.WaitAll(produceTask,consumeTask);Console.WriteLine("\n所有操作完成!");}}

总结

通过ConcurrentQueue和ConcurrentDictionary实现了一个线程安全的进程内消息队列。该方案支持Key绑定机制简化队列管理,提供完整的生产消费示例,适用于多线程数据交换场景,具备高性能和易用性特点。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 17:03:50

对比:传统排查vsAI解决无编译器问题的效率差异

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个效率对比演示工具&#xff1a;左侧模拟传统排查流程(查文档/论坛/试错)&#xff0c;右侧展示AI解决方案。功能包括&#xff1a;1. 实时记录两种方式的时间消耗 2. 关键节点…

作者头像 李华
网站建设 2026/6/15 17:39:51

SSL证书过期?5分钟教你紧急处理

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 生成一个交互式新手教程&#xff0c;用户输入自己的域名后&#xff0c;工具自动检测证书状态。如果过期&#xff0c;逐步引导用户&#xff1a;1) 如何生成CSR 2) 选择CA 3) 安装新…

作者头像 李华
网站建设 2026/6/15 18:59:47

通义千问3-4B性能优化:让树莓派AI速度提升3倍

通义千问3-4B性能优化&#xff1a;让树莓派AI速度提升3倍 导语&#xff1a;随着边缘计算与端侧AI的快速发展&#xff0c;如何在资源受限设备上高效运行大语言模型成为关键挑战。通义千问3-4B-Instruct-2507&#xff08;Qwen3-4B-Instruct-2507&#xff09;作为阿里2025年8月开…

作者头像 李华
网站建设 2026/6/15 16:28:16

Holistic Tracking实时渲染方案:云GPU+WebRTC低延迟传输

Holistic Tracking实时渲染方案&#xff1a;云GPUWebRTC低延迟传输 引言&#xff1a;在线教育的实时互动难题 想象一下在线舞蹈教学场景&#xff1a;学员跟着屏幕里的老师学习动作&#xff0c;但视频反馈总是慢半拍。当你已经做完一个转身动作&#xff0c;屏幕里的虚拟老师才…

作者头像 李华
网站建设 2026/6/6 7:40:17

AI助力Linux学习:智能代码生成与调试

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个基于AI的Linux学习助手&#xff0c;能够根据用户输入的自然语言描述自动生成相应的Linux命令和脚本。例如&#xff0c;当用户输入如何批量重命名当前目录下所有.txt文件为…

作者头像 李华
网站建设 2026/6/15 17:55:20

TERA TERM新手教程:从零开始学习终端模拟器的基本使用

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个交互式TERA TERM学习助手&#xff0c;通过步骤式引导帮助新手掌握基本操作。内容包括&#xff1a;1)安装与配置向导&#xff0c;2)连接设备演示&#xff0c;3)常用命令练习…

作者头像 李华