我通过串口将秤连接到计算机。我在循环内达到0时检查值SerialPort.BytesToRead。然而,即使BytesToRead不等于0,循环也会退出。我无法发布屏幕截图,因为我是新用户但是通过调试我可以看到BytesToRead实际上不是0。
这导致我的数据无法完全读取。我尝试过不同的表达式,例如_port.BytesToRead > 0
,但结果是一样的。即使将BytesToRead的值赋给变量也会给出0.如果没有循环,ReadExisting不会返回从scale发送的所有数据,所以我真的没有选择。 ReadLine也不起作用。那么为什么BytesToRead总是0?
private void PortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
{
var input = string.Empty;
// Reads the data one by one until it reaches the end
do
{
input += _port.ReadExisting();
} while (_port.BytesToRead != 0);
_scaleConfig = GenerateConfig(input);
if (ObjectReceived != null)
ObjectReceived(this, _scaleConfig);
}
}
答案 0 :(得分:2)
我的老板弄清楚了。这是代码。
private void PortDataReceived2(object sender, SerialDataReceivedEventArgs e)
{
var bytesToRead = _port.BytesToRead;
_portDataReceived.Append(_port.ReadExisting());
// Buffer wasn't full. We are at the end of the transmission.
if (bytesToRead < _port.DataBits)
{
//Console.WriteLine(string.Format("Final Data received: {0}", _portDataReceived));
IScalePropertiesBuilder scaleReading = null;
scaleReading = GenerateConfig(_portDataReceived.ToString());
_portDataReceived.Clear();
if (ObjectReceived != null)
{
ObjectReceived(this, scaleReading);
}
}
}
答案 1 :(得分:2)
您的原始代码很奇怪,因为我没有看到代码知道缓冲区是否为空,因为您的代码已清空,或者因为设备尚未发送。 (这似乎是你设计中的一个基本问题:你想要读取所有字节,但只有在你读完所有字节后才能知道应该有多少字节。)
你后来的代码甚至更奇怪,因为DataBits是每字节位数(5到8之间)的串行配置 - 只有在RS232中才能有一个字节小于8位。
那就是说,我在BytesToRead周围看到了非常奇怪的行为。在我看来,它几乎完全不可靠,只有在它有用之后才能更新。在MSDN上有一个关于它不一致的说明,但它不包括它莫名其妙地0的情况,我也看到了。
答案 2 :(得分:1)
也许当你运行调试器时,它的速度足够慢,实际上有字节需要读取,但是当你在没有调试器的情况下运行它时,因此没有发生断点,它最终退出循环之前的设备串口有时间发送数据。最有可能的是,ReadExisting将读取端口上的所有数据,然后立即退出,因为端口上没有新数据。也许为了缓解这个问题,您可以在读取数据之间进行一些小的等待(可能使用Thread.Sleep()),并通过检查BytesToRead的值来检查是否有更多数据。虽然您可能应该查看您正在阅读的数据,以确定您何时读取所有必要的数据,无论您尝试接收的是什么。