news 2026/7/15 6:13:50

基于C#实现多线程串口通信

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于C#实现多线程串口通信

一、核心架构设计

主线程

SerialPortManager

接收线程

发送线程

数据缓冲队列

数据处理线程


二、关键代码实现

1. 串口管理类(线程安全封装)
usingSystem.IO.Ports;usingSystem.Threading;usingSystem.Collections.Concurrent;publicclassSerialPortManager:IDisposable{privateSerialPort_serialPort;privateThread_readThread;privateThread_writeThread;privateConcurrentQueue<byte[]>_dataQueue=newConcurrentQueue<byte[]>();privateAutoResetEvent_writeEvent=newAutoResetEvent(false);privateSemaphoreSlim_serialLock=newSemaphoreSlim(1,1);publiceventAction<byte[]>DataReceived;publicSerialPortManager(stringportName,intbaudRate){InitializePort(portName,baudRate);StartThreads();}privatevoidInitializePort(stringportName,intbaudRate){_serialPort=newSerialPort(portName,baudRate){Parity=Parity.None,DataBits=8,StopBits=StopBits.One,ReadTimeout=500,WriteTimeout=500};_serialPort.DataReceived+=(s,e)=>{varbuffer=newbyte[_serialPort.BytesToRead];_serialPort.Read(buffer,0,buffer.Length);_dataQueue.Enqueue(buffer);DataReceived?.Invoke(buffer);};}privatevoidStartThreads(){_readThread=newThread(ProcessIncomingData);_writeThread=newThread(ProcessOutgoingData);_readThread.Start();_writeThread.Start();}publicasyncTaskSendDataAsync(byte[]data){await_serialLock.WaitAsync();try{_writeEvent.Set();_serialPort.Write(data,0,data.Length);}finally{_serialLock.Release();}}privatevoidProcessIncomingData(){while(!_serialPort.IsOpen)Thread.Sleep(100);while(true){if(_dataQueue.TryDequeue(outvardata)){// 数据解析逻辑ParseData(data);}Thread.Sleep(10);}}privatevoidProcessOutgoingData(){while(true){_writeEvent.WaitOne();// 发送队列处理逻辑}}privatevoidParseData(byte[]data){// 实现具体协议解析}publicvoidDispose(){_serialLock.Dispose();_writeEvent.Dispose();_serialPort?.Close();_serialPort?.Dispose();}}

三、线程同步机制

1. 双缓冲队列设计
privateConcurrentQueue<byte[]>_readBuffer=newConcurrentQueue<byte[]>();privateConcurrentQueue<byte[]>_processBuffer=newConcurrentQueue<byte[]>();// 数据接收线程voidReceiveThread(){while(true){if(_serialPort.BytesToRead>0){varbuffer=newbyte[_serialPort.BytesToRead];_serialPort.Read(buffer,0,buffer.Length);_readBuffer.Enqueue(buffer);}Thread.Sleep(1);}}// 数据处理线程voidProcessThread(){while(true){if(_readBuffer.TryDequeue(outvardata)){_processBuffer.Enqueue(ProcessData(data));}}}
2. 异步读写实现
publicasyncTask<byte[]>ReadAsync(CancellationTokenct){await_serialLock.WaitAsync(ct);try{varbuffer=newbyte[1024];intbytesRead=await_serialPort.BaseStream.ReadAsync(buffer,0,buffer.Length,ct);Array.Resize(refbuffer,bytesRead);returnbuffer;}finally{_serialLock.Release();}}publicasyncTaskWriteAsync(byte[]data,CancellationTokenct){await_serialLock.WaitAsync(ct);try{await_serialPort.BaseStream.WriteAsync(data,0,data.Length,ct);}finally{_serialLock.Release();}}

四、异常处理

1. 异常捕获框架
publicvoidSafeWrite(byte[]data){try{_serialLock.Wait();_serialPort.Write(data,0,data.Length);}catch(TimeoutExceptionex){HandleTimeout();}catch(IOExceptionex){HandleDeviceDisconnect();}finally{_serialLock.Release();}}
2. 自动重连机制
privatevoidHandleDeviceDisconnect(){_serialLock.Wait();try{if(_serialPort.IsOpen)_serialPort.Close();Thread.Sleep(1000);ReinitializePort();}finally{_serialLock.Release();}}privatevoidReinitializePort(){InitializePort(_config.PortName,_config.BaudRate);StartThreads();}

参考代码 c#编写串口通讯代码多线程www.youwenfan.com/contentcsr/111962.html

五、性能优化

1. 内存池管理
privateObjectPool<byte[]>_bufferPool=newObjectPool<byte[]>(()=>newbyte[1024],10);byte[]GetBuffer()=>_bufferPool.Get();voidReturnBuffer(byte[]buffer)=>_bufferPool.Return(buffer);
2. 批量数据处理
publicvoidProcessBatchData(IEnumerable<byte[]>dataArray){Parallel.ForEach(dataArray,data=>{varparsed=ParseData(data);lock(_processedData){_processedData.Add(parsed);}});}

六、完整使用示例

varmanager=newSerialPortManager("COM3",115200);// 异步发送数据awaitmanager.SendDataAsync(Encoding.UTF8.GetBytes("Hello"));// 接收回调处理manager.DataReceived+=(data)=>{vartext=Encoding.UTF8.GetString(data);Console.WriteLine($"Received:{text}");};// 后台数据处理Task.Run(()=>{while(true){if(manager.TryDequeueProcessedData(outvardata)){UpdateUI(data);}}});

七、调试与监控

1. 日志记录
publicvoidLogCommunication(stringmessage){lock(_logLock){File.AppendAllText("com_log.txt",$"{DateTime.Now:HH:mm:ss.fff}-{message}{Environment.NewLine}");}}
2. 实时状态监控
publicclassSerialStatus{publicintBytesSent{get;privateset;}publicintBytesReceived{get;privateset;}publicvoidIncrementSent(intcount)=>BytesSent+=count;publicvoidIncrementReceived(intcount)=>BytesReceived+=count;}

八、扩展功能实现

1. 协议解析器
publicclassModbusParser{publicstaticDictionary<byte,ushort>ParseFrame(byte[]data){// 实现Modbus RTU协议解析returnnewDictionary<byte,ushort>();}}
2. 加密传输
publicclassSecureSerialPort{privateAes_aes=Aes.Create();publicbyte[]Encrypt(byte[]data){using(varencryptor=_aes.CreateEncryptor())using(varms=newMemoryStream()){cs.Write(data,0,data.Length);returnms.ToArray();}}}

九、最佳实践建议

  1. 线程模型选择

    • 优先使用Task替代传统Thread

    • 高频数据采用BlockingCollection实现生产者-消费者模式

  2. 资源管理规范

    using(varmanager=newSerialPortManager()){// 自动释放资源}
  3. 性能监控指标

    • 串口缓冲区占用率

    • 数据处理延迟

    • 异常发生频率

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

第三章 数组

3.1 数组的概述 数组本身是引用数据类型&#xff0c;而数组中的元素可以是任何数据类型&#xff0c;包括 基本数据类型和引用数据类型。  创建数组对象会在内存中开辟一整块连续的空间&#xff0c;而数组名中引用的是 这块连续空间的首地址。  数组的长度一旦确定&#x…

作者头像 李华
网站建设 2026/7/1 11:24:04

在洗浴中心泡澡时睡着会溺水吗?一场关于安全与放松的闲谈

在忙碌的生活节奏里&#xff0c;洗浴中心成了很多人放松身心的“避风港”。泡在温热的池水中&#xff0c;感受着水流轻柔的包裹&#xff0c;疲惫与压力仿佛都被一点点抽离&#xff0c;不少人会在这种惬意的状态下不知不觉闭上眼睛&#xff0c;甚至进入浅睡眠。然而&#xff0c;…

作者头像 李华
网站建设 2026/7/15 1:03:37

WordPress定制开发自动化测试最佳实践

为什么WordPress定制开发需要自动化测试多年的WordPress定制开发经验中&#xff0c;发现许多项目在上线后出现的问题&#xff0c;往往源于测试不充分。传统的手工测试不仅耗时费力&#xff0c;还容易遗漏关键场景。自动化测试的引入彻底改变了这一局面。通过自动化测试&#xf…

作者头像 李华
网站建设 2026/7/7 21:44:30

这款产品解锁《秘奥:秘宇奥忆》沉浸式星际探秘

当腐朽奢华的太空废土遇上高速流畅的类银河恶魔城玩法&#xff0c;法国独立工作室 Douze Diximes 打造的《秘奥&#xff1a;秘宇奥忆》&#xff0c;将漫画线条、水彩质感与油画诗意熔于一炉&#xff0c;在锈蚀机械与葱郁植被的碰撞中&#xff0c;构筑出孤独又浪漫的星际方舟世界…

作者头像 李华
网站建设 2026/7/7 21:46:20

代码是如何变成可执行文件的?

代码是如何变成可执行文件的&#xff1f;—— 深入理解编译全过程 起因 前几天在公司&#xff0c;我的 mentor 突然问我&#xff1a;“代码在编译过程中&#xff0c;预处理阶段到底在做什么&#xff1f;” 我愣了一下&#xff0c;发现自己对这块知识的理解确实有些模糊。虽然每…

作者头像 李华
网站建设 2026/7/7 21:44:19

字节这款新AI让导演都慌了!Seedance2.0凭什么能自动剪大片?

&#x1f4cc; 目录&#x1f3ac; 字节杀疯了&#xff01;Seedance2.0自动剪大片&#xff0c;导演都慌了&#xff1a;这是要抢饭碗&#xff1f;一、核心黑科技&#xff1a;双分支大脑&#xff0c;终结AI音画错位的噩梦二、实测封神&#xff1a;多模态神操作&#xff0c;细节碾压…

作者头像 李华