C#串口SerialPort使用事件触发和线程查询数据接收都不完整?
C#上位机给下位机发送查询命令,下位机收到后返回数据,上位机每1s查询一次,上下位机通讯数据格式都是:若干字节\r\n
我用2个线程来处理,一个专门收串口数据,送到缓冲区中,一个从缓冲区读数据然后处理数据,应该不是因为数据处理太慢导致数据丢失的吧。
波特率为2400,ReadBufferSize为4096
1、使用DataReceived事件
ReceivedBytesThreshold为1
com.ReadTo("\r\n");
com.DiscardInBuffer();
理论上应该收到:3C030729211412121412,但几乎每次收到的都是:3C0307。按照网上的办法,修改如下:
private void com_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
com.ReceivedBytesThreshold = 10000;
com.ReadTo("\r\n");
com.DiscardInBuffer();
将数据写入缓冲区;
com.ReceivedBytesThreshold = 1;
}
以及
private void com_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
System.Threading.Thread.Sleep(20);
com.ReadTo("\r\n");
将数据写入缓冲区;
com.DiscardInBuffer();
}
收到的数据还是不完整,最后我改成
private void com_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
com.DataReceived -= new SerialDataReceivedEventHandler(com_DataReceived);
while (com.BytesToRead > 0)
{
com.ReadByte();
将数据写入缓冲区;
}
com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived);
}
这样才能完整的收到数据。
2、使用线程查询串口数据
private void ComMonitorThread()
{
while (true)
{
if (com.BytesToRead > 0)
{
byte[] buffer = new byte[com.BytesToRead];
com.Read(buffer, 0, com.BytesToRead);
将数据写入缓冲区;
}
}
}
理论上应该收到:3C030729211412121412,但几乎每次收到的都是:3C03072121412,前后部分数据都对,但中间的2921141却丢失了。最后改成如下方式才没有丢数据。
private void ComMonitorThread()
{
while (true)
{
if (com.BytesToRead > 0)
{
com.ReadByte();
将数据写入缓冲区;
}
}
}
3、无论用com.Read(buffer, 0, com.BytesToRead),还是com.ReadTo("\r\n"),还是com.ReadLine(),还是com.ReadExisting(),读出来的数据都不完整。只用com.ReadByte()才能读出完整的数据。但是这样CPU占用率都高达99%,不知大家有没有什么更好的解决方案。