0

我正在通过串行端口将秤连接到计算机。我检查值 SerialPort.BytesToRead 当它在循环内达到 0 时。但是,即使 BytesToRead 不等于 0,循环也会退出。我无法发布屏幕截图,因为我是新用户,但通过调试我可以看到 BytesToRead 实际上不是 0。

这导致我的数据没有被完全读取。我尝试过不同的表达方式,例如,_port.BytesToRead > 0但结果是一样的。即使将 BytesToRead 的值分配给变量也会给出 0。没有循环,ReadExisting 不会返回从秤发送的所有数据,所以我真的别无选择。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);
        }
    }
4

3 回答 3

2

您的原始代码很奇怪,因为无论如何我都看不到代码知道缓冲区是否为空,因为您的代码已清空缓冲区,还是因为设备尚未发送。(这似乎是您设计中的一个基本问题:您想读取直到获得所有字节,但只有在读取所有字节之后才能弄清楚应该有多少字节)。

您以后的代码甚至更奇怪,因为 DataBits 是每个字节的位数(包括 5 到 8 之间)的串行配置——只有在 RS232 中,一个字节才能小于 8 位。

也就是说,我在 BytesToRead 周围看到了非常奇怪的行为。在我看来,它几乎完全不可靠,只有在它有用后才能更新。MSDN上有一条关于它不一致的注释,但它不包括它莫名其妙地为0的情况,我也看到了。

于 2012-11-10T00:32:28.447 回答
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);
            }
        }
    }
于 2012-06-04T13:59:13.837 回答
1

也许当您运行调试器时,它的速度已经足够慢以至于实际上有字节要读取,但是当您在没有调试器的情况下运行它并且因此没有发生断点时,它最终会在串行端口上的设备之前退出循环有发送数据的时间。ReadExisting 很可能会读取端口上的所有数据,然后立即退出,因为端口上没有新数据。也许为了缓解这个问题,您可以在读取数据和通过检查 BytesToRead 的值来检查是否有更多数据之间稍作等待(可能使用 Thread.Sleep())。尽管您可能应该查看您正在读取的数据,以确定您何时实际上已经读取了您尝试接收的所有必要数据。

于 2012-05-30T20:25:47.540 回答