基于C#实现多线程串口通信的完整代码
更新时间:2026年06月08日 08:40:31 作者:jllllyuz
这篇文章主要为大家详细介绍了使用C#实现多线程串口通信的方法,涵盖关键代码实现、线程同步机制、异常处理及性能优化等内容,适合开发人员参考学习
一、核心架构设计

二、关键代码实现
串口管理类(线程安全封装)
using System.IO.Ports;
using System.Threading;
using System.Collections.Concurrent;
public class SerialPortManager : IDisposable
{
private SerialPort _serialPort;
private Thread _readThread;
private Thread _writeThread;
private ConcurrentQueue<byte[]> _dataQueue = new ConcurrentQueue<byte[]>();
private AutoResetEvent _writeEvent = new AutoResetEvent(false);
private SemaphoreSlim _serialLock = new SemaphoreSlim(1, 1);
public event Action<byte[]> DataReceived;
public SerialPortManager(string portName, int baudRate)
{
InitializePort(portName, baudRate);
StartThreads();
}
private void InitializePort(string portName, int baudRate)
{
_serialPort = new SerialPort(portName, baudRate)
{
Parity = Parity.None,
DataBits = 8,
StopBits = StopBits.One,
ReadTimeout = 500,
WriteTimeout = 500
};
_serialPort.DataReceived += (s, e) =>
{
var buffer = new byte[_serialPort.BytesToRead];
_serialPort.Read(buffer, 0, buffer.Length);
_dataQueue.Enqueue(buffer);
DataReceived?.Invoke(buffer);
};
}
private void StartThreads()
{
_readThread = new Thread(ProcessIncomingData);
_writeThread = new Thread(ProcessOutgoingData);
_readThread.Start();
_writeThread.Start();
}
public async Task SendDataAsync(byte[] data)
{
await _serialLock.WaitAsync();
try
{
_writeEvent.Set();
_serialPort.Write(data, 0, data.Length);
}
finally
{
_serialLock.Release();
}
}
private void ProcessIncomingData()
{
while (!_serialPort.IsOpen) Thread.Sleep(100);
while (true)
{
if (_dataQueue.TryDequeue(out var data))
{
// 数据解析逻辑
ParseData(data);
}
Thread.Sleep(10);
}
}
private void ProcessOutgoingData()
{
while (true)
{
_writeEvent.WaitOne();
// 发送队列处理逻辑
}
}
private void ParseData(byte[] data)
{
// 实现具体协议解析
}
public void Dispose()
{
_serialLock.Dispose();
_writeEvent.Dispose();
_serialPort?.Close();
_serialPort?.Dispose();
}
}三、线程同步机制
1. 双缓冲队列设计
private ConcurrentQueue<byte[]> _readBuffer = new ConcurrentQueue<byte[]>();
private ConcurrentQueue<byte[]> _processBuffer = new ConcurrentQueue<byte[]>();
// 数据接收线程
void ReceiveThread()
{
while (true)
{
if (_serialPort.BytesToRead > 0)
{
var buffer = new byte[_serialPort.BytesToRead];
_serialPort.Read(buffer, 0, buffer.Length);
_readBuffer.Enqueue(buffer);
}
Thread.Sleep(1);
}
}
// 数据处理线程
void ProcessThread()
{
while (true)
{
if (_readBuffer.TryDequeue(out var data))
{
_processBuffer.Enqueue(ProcessData(data));
}
}
}2. 异步读写实现
public async Task<byte[]> ReadAsync(CancellationToken ct)
{
await _serialLock.WaitAsync(ct);
try
{
var buffer = new byte[1024];
int bytesRead = await _serialPort.BaseStream.ReadAsync(buffer, 0, buffer.Length, ct);
Array.Resize(ref buffer, bytesRead);
return buffer;
}
finally
{
_serialLock.Release();
}
}
public async Task WriteAsync(byte[] data, CancellationToken ct)
{
await _serialLock.WaitAsync(ct);
try
{
await _serialPort.BaseStream.WriteAsync(data, 0, data.Length, ct);
}
finally
{
_serialLock.Release();
}
}四、异常处理
1. 异常捕获框架
public void SafeWrite(byte[] data)
{
try
{
_serialLock.Wait();
_serialPort.Write(data, 0, data.Length);
}
catch (TimeoutException ex)
{
HandleTimeout();
}
catch (IOException ex)
{
HandleDeviceDisconnect();
}
finally
{
_serialLock.Release();
}
}2. 自动重连机制
private void HandleDeviceDisconnect()
{
_serialLock.Wait();
try
{
if (_serialPort.IsOpen) _serialPort.Close();
Thread.Sleep(1000);
ReinitializePort();
}
finally
{
_serialLock.Release();
}
}
private void ReinitializePort()
{
InitializePort(_config.PortName, _config.BaudRate);
StartThreads();
}五、性能优化
1. 内存池管理
private ObjectPool<byte[]> _bufferPool = new ObjectPool<byte[]>(() => new byte[1024], 10); byte[] GetBuffer() => _bufferPool.Get(); void ReturnBuffer(byte[] buffer) => _bufferPool.Return(buffer);
2. 批量数据处理
public void ProcessBatchData(IEnumerable<byte[]> dataArray)
{
Parallel.ForEach(dataArray, data =>
{
var parsed = ParseData(data);
lock (_processedData)
{
_processedData.Add(parsed);
}
});
}六、完整使用示例
var manager = new SerialPortManager("COM3", 115200);
// 异步发送数据
await manager.SendDataAsync(Encoding.UTF8.GetBytes("Hello"));
// 接收回调处理
manager.DataReceived += (data) =>
{
var text = Encoding.UTF8.GetString(data);
Console.WriteLine($"Received: {text}");
};
// 后台数据处理
Task.Run(() =>
{
while (true)
{
if (manager.TryDequeueProcessedData(out var data))
{
UpdateUI(data);
}
}
});七、调试与监控
1. 日志记录
public void LogCommunication(string message)
{
lock (_logLock)
{
File.AppendAllText("com_log.txt",
$"{DateTime.Now:HH:mm:ss.fff} - {message}{Environment.NewLine}");
}
}2. 实时状态监控
public class SerialStatus
{
public int BytesSent { get; private set; }
public int BytesReceived { get; private set; }
public void IncrementSent(int count) => BytesSent += count;
public void IncrementReceived(int count) => BytesReceived += count;
}八、扩展功能实现
1. 协议解析器
public class ModbusParser
{
public static Dictionary<byte, ushort> ParseFrame(byte[] data)
{
// 实现Modbus RTU协议解析
return new Dictionary<byte, ushort>();
}
}2. 加密传输
public class SecureSerialPort
{
private Aes _aes = Aes.Create();
public byte[] Encrypt(byte[] data)
{
using (var encryptor = _aes.CreateEncryptor())
using (var ms = new MemoryStream())
{
cs.Write(data, 0, data.Length);
return ms.ToArray();
}
}
}九、最佳实践建议
线程模型选择
- 优先使用
Task替代传统Thread - 高频数据采用
BlockingCollection实现生产者-消费者模式
资源管理规范
using (var manager = new SerialPortManager())
{
// 自动释放资源
}性能监控指标
- 串口缓冲区占用率
- 数据处理延迟
- 异常发生频率
到此这篇关于基于C#实现多线程串口通信的完整代码的文章就介绍到这了,更多相关C#多线程串口通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!


最新评论