SerialPort.BytesToRead总是被评估为0,即使它不是

时间:2012-05-30 20:16:52

标签: c# serial-port

我通过串口将秤连接到计算机。我在循环内达到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);
        }
    }

3 个答案:

答案 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的值来检查是否有更多数据。虽然您可能应该查看您正在阅读的数据,以确定您何时读取所有必要的数据,无论您尝试接收的是什么。