本文章介绍了在C#编程环境中实现多线程和串口通信的方法和技术,帮助开发者构建高效、稳定的串行数据处理应用。
这是一个非常经典的C#串口多线程实例。以下是部分代码供参考:
```csharp
using System;
using System.IO;
using System.IO.Ports;
using System.Collections;
using System.Threading;
namespace Termie
{
///
/// CommPort类创建SerialPort(System.IO.Ports)的单例实例。
///
public sealed class CommPort
{
SerialPort _serialPort; //串口对象
Thread _readThread; //读取线程
volatile bool _keepReading; //标志位,用于控制是否继续读取
static readonly CommPort instance = new CommPort(); //单例模式初始化
private CommPort()
{
_serialPort = new SerialPort();
_readThread = null;
_keepReading = false;
}
public static CommPort Instance { get { return instance; } }
//观察者模式
public delegate void EventHandler(string param);
public EventHandler StatusChanged; //状态改变事件处理程序
public EventHandler DataReceived; //数据接收事件处理程序
private void StartReading()
{
if (!_keepReading)
{
_keepReading = true;
_readThread = new Thread(ReadPort);
_readThread.Start();
}
}
private void StopReading()
{
if (_keepReading)
{
_keepReading = false;
_readThread.Join(); //等待线程退出
_readThread = null;
}
}
///
/// 读取串口数据并传递给事件处理程序。
///
private void ReadPort()
{
while (_keepReading)
{
if (_serialPort.IsOpen)
{
byte[] readBuffer = new byte[_serialPort.ReadBufferSize + 1];
try
{
int count = _serialPort.Read(readBuffer, 0, _serialPort.ReadBufferSize);
string SerialIn = System.Text.Encoding.ASCII.GetString(readBuffer, 0, count);
DataReceived(SerialIn);
}
catch (TimeoutException) { } //忽略超时异常
}
else
{
TimeSpan waitTime = new TimeSpan(0, 0, 0, 0, 50);
Thread.Sleep(waitTime);
}
}
}
///
/// 打开串口,使用当前设置。
///
public void Open()
{
Close();
try
{
_serialPort.PortName = Settings.Port.PortName;
_serialPort.BaudRate = Settings.Port.BaudRate;
_serialPort.Parity = Settings.Port.Parity;
_serialPort.DataBits = Settings.Port.DataBits;
_serialPort.StopBits = Settings.Port.StopBits;
_serialPort.Handshake = Settings.Port.Handshake;
// 设置读写超时
_serialPort.ReadTimeout = 50;
_serialPort.WriteTimeout = 50;
_serialPort.Open();
StartReading();
}
catch (IOException) { StatusChanged(String.Format({0} does not exist, Settings.Port.PortName)); }
catch (UnauthorizedAccessException) { StatusChanged(String.Format({0} already in use, Settings.Port.PortName)); }
catch (Exception ex) { StatusChanged(String.Format({0}, ex.ToString())); }
if (_serialPort.IsOpen)
// 更新状态信息
string p = _serialPort.Parity.ToString().Substring(0, 1);
string h = _serialPort.Handshake.ToString();
if(_serialPort.Handshake == Handshake.None)
h = no handshake;
StatusChanged(String.Format({0}: {1} bps, {2}{3}{4}, {5},
_serialPort.PortName,
_serialPort.BaudRate,
_serialPort.DataBits, p, (int)_serialPort.StopBits, h));
else
StatusChanged(String.Format({0} already in use, Settings.Port.PortName));
}
///
/// 关闭串口。
///
public void Close()
{
StopReading();
_serialPort.Close();
StatusChanged(connection closed);
}
// 获取串口状态
public bool IsOpen { get { return _serialPort.IsOpen; } }
//获取可用的端口号列表。
public string[] GetAvailablePorts()
{
return SerialPort.GetPortNames();
}
///
/// 向串口发送数据,并在末尾添加换行符。
///
public void Send(string data)
{