目录
获取PC上所有的串口
public static string[] GetPortNames();
构造函数(设置串口参数)
public SerialPort(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits);
判断串口打开/关闭
public bool IsOpen { get; }
打开串口
public void Open();
关闭串口
public void Close();
发送数据
public void Write(byte[] buffer, int offset, int count);
public void Write(string text);
public void Write(char[] buffer, int offset, int count);
public void WriteLine(string text);
读取数据
public int Read(byte[] buffer, int offset, int count);
public string ReadExisting();
public int Read(char[] buffer, int offset, int count);
public int ReadByte();
public int ReadChar();
public string ReadLine();
超时设置
public int ReadTimeout { get; set; }
public int WriteTimeout { get; set; }
接收到多少字节触发一次DataReceived事件
public int ReceivedBytesThreshold { get; set; }
清空接收和发送缓存
public void DiscardInBuffer();
public void DiscardOutBuffer();
串口收到数据触发的事件
public event SerialDataReceivedEventHandler DataReceived;
C#串口编程中的重难点
- 在DataReceived事件访问UI控件,会抛出InvalidOperationException异常
原因:当数据到达后,.NET开启一个工作线程(非UI线程)去执行DataReceived事件,所以,如果我们注册到DataReceived事件的方法若是访问只能在UI线程中访问的控件,肯定会抛出异常的。 - ReceivedBytesThreshold的值对程序性能的影响
ReceivedBytesThreshold决定串口缓存接收到多少个字节才会触发一次DataReceived事件,默认值是1.假设串口通信的协议最短的指令长度是10个字节,显然我们把ReceivedBytesThreshold设置成10比设置成1更加合理。 - 如果通信十分频繁,可能存在多个线程都在执行DataReceived事件,所以我们要根据实际场景,酌情考虑是否在要注册到DataReceived事件的方法中加锁以保证永远只有一个线程在执行DataReceived事件。
- 我们经常会在DataReceived事件中,把接收到的数据打印到UI界面,然后在UI界面上有个Button用来关闭串口。代码大致如下:
这种代码存在bug:当我们点击关闭按钮后,会偶发界面卡死。原因是发生了线程死锁,解决方法是,DataReceived事件中访问UI元素用BeginInvoke,不要用Invoke。
详细请访问
C# 串口关闭时主界面卡死原因分析