我很尴尬不得不问这样一个问题,但我很难搞清楚如何通过.NET SerialPort类在串口上可靠地读取数据.
我的第一个方法:
static void Main(string[] args)
{
_port = new SerialPort
{
PortName = portName,
BaudRate = 57600,
DataBits = 8,
Parity = Parity.None,
StopBits = StopBits.One,
RtsEnable = true,
DtrEnable = false,
WriteBufferSize = 2048,
ReadBufferSize = 2048,
ReceivedBytesThreshold = 1,
ReadTimeout = 5000,
};
_port.DataReceived += _port_DataReceived;
_port.Open();
// whatever
}
private void _port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var buf = new byte[_port.BytesToRead];
var bytesRead = _port.Read(buf, 0, buf.Length);
_port.DiscardInBuffer();
for (int i = 0; i < bytesRead; ++i)
{
// read each byte, look for start/end values,
// signal complete packet event if/when end is found
}
}
Run Code Online (Sandbox Code Playgroud)
所以这有一个明显的问题; 我正在调用DiscardInBuffer,所以在事件被触发后进入的任何数据都被丢弃,即我正在丢弃数据.
现在,SerialPort.Read()的文档甚至没有声明它是否提前了当前位置的流(真的吗?),但我发现其他来源声称它确实(这是有道理的).但是,如果我不调用DiscardInBuffer我最终会收到RXOver错误,即我花了太长时间处理每条消息并且缓冲区溢出.
所以...我真的不喜欢这个界面.如果我必须在一个单独的线程上处理每个缓冲区,我会这样做,但是它带有一系列问题,我希望我错过了一些东西,因为我对这个界面没有多少经验.
Jason提出了一些关于减少来自工作线程的UI访问的好点,但更好的选择是首先不在工作线程上接收数据.
用于port.BaseStream.ReadAsync在您想要的线程上获取事件驱动的数据.我在http://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport上写了更多关于这种方法的文章.
| 归档时间: |
|
| 查看次数: |
9258 次 |
| 最近记录: |