新加监听标记,界面关闭时停止读取串口数据,防止异步数据展示报错
串口读取出错,在创建窗口句柄之前,不能在控件上调用 invoke 或 Beginimvoke
1.串口初始化
SerialPort serialPort1 = new SerialPort();
serialPort1.PortName = "COM1";
serialPort1.BaudRate = 9600;
serialPort1.Parity = Parity.None;
serialPort1.StopBits = StopBits.One;
serialPort1.DataBits = 8;
serialPort1.Handshake = Handshake.None;
SerialPort serialPort2 = new SerialPort();
serialPort2.PortName = "COM2";
serialPort2.BaudRate = 9600;
serialPort2.Parity = Parity.None;
serialPort2.StopBits = StopBits.One;
serialPort2.DataBits = 8;
serialPort2.Handshake = Handshake.None;
//数据展示
public delegate void Displaydelegate(string indata);
public Displaydelegate disp_delegate= new Displaydelegate(DispUI);
//新加监听标记
public CancellationTokenSource cancellationTokenSource1 = new CancellationTokenSource();
public CancellationTokenSource cancellationTokenSource2 = new CancellationTokenSource();
2.串口接收事件
通过异步多线程进行接收,不会导致界面卡顿
Task.Run(() => {
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
serialPort2.DataReceived += new SerialDataReceivedEventHandler(serialPort2_DataReceived);
});
取数处理字符串的方式可能不太合理
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
if (serialPort1.IsOpen&&!cancellationTokenSource1.IsCancellationRequested)
{
Thread.Sleep(100); //(毫秒)等待一定时间,确保数据的完整性
int len = serialPort1.BytesToRead;
byte[] buff = new byte[len];
serialPort1.Read(buff, 0, len);
var alldata = Encoding.Default.GetString(buff);
var indata = alldata;
if (alldata.Contains("+") && alldata.Length - alldata.IndexOf('+') >= 7)
{
indata = alldata.Substring(alldata.IndexOf('+') + 1, 6);//000304 +000628314
}
if (alldata.Contains("-") && alldata.Length - alldata.IndexOf('-') >= 7)
{
indata = alldata.Substring(alldata.IndexOf('-') + 1, 6);// -00015031A
indata = "-" + indata;
}
if (!string.IsNullOrEmpty(indata) && indata.Length > 0)
{
this.Invoke(disp_delegate, indata);
}
}
}
catch (Exception ex)
{
MsgBox.Information("串口1读取出错," + ex.Message);
return;
}
}
private void serialPort2_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
if (serialPort2.IsOpen&&!cancellationTokenSource2.IsCancellationRequested)
{
Thread.Sleep(100); //(毫秒)等待一定时间,确保数据的完整性
int len = serialPort2.BytesToRead;
byte[] buff = new byte[len];
serialPort2.Read(buff, 0, len);
var alldata = Encoding.Default.GetString(buff);
var indata = alldata;
if (alldata.Contains("+") && alldata.Length - alldata.IndexOf('+') >= 8)
{
indata = alldata.Substring(alldata.IndexOf('+') + 1, 7);//000304 +000628314
}
if (alldata.Contains("-") && alldata.Length - alldata.IndexOf('-') >= 8)
{
indata = alldata.Substring(alldata.IndexOf('-') + 1, 7);// -00015031A
indata = "-" + indata;
}
if (!string.IsNullOrEmpty(indata) && indata.Length > 0)
{
this.Invoke(disp_delegate, indata);
}
}
}
catch (Exception ex)
{
MsgBox.Information("串口2读取出错," + ex.Message);
return;
}
}
3.串口接收数据展示
public void DispUI(string indata)
{
控件值=indata;
}
4.界面关闭关闭串口
try
{
cancellationTokenSource1.Cancel(); // 取消监听任务
cancellationTokenSource2.Cancel(); // 取消监听任务
serialPort1.DiscardInBuffer(); // 清空输入缓冲区(可选)
serialPort2.DiscardInBuffer(); // 清空输入缓冲区(可选)
if (serialPort1 != null && serialPort1.IsOpen)
{//关闭串口
serialPort1.Close();
}
if (serialPort2 != null && serialPort2.IsOpen)
{//关闭串口
serialPort2.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}