【问题标题】:BytesToRead is greater than ReadBufferSizeBytesToRead 大于 ReadBufferSize
【发布时间】:2013-01-08 01:17:27
【问题描述】:

我正在调试一些串行的东西,重要的部分是 SerialDataReceivedEventHandler。

我观察到(通过断点和悬停)读取的字节数几乎是缓冲区大小本身的两倍。喜欢吗?

这是代码

aUartSemaphoreThatTells.WhatTheUartBackgroundRxIsDoing = (int)aValueWhichIndicatesThat.theUARTisReceivingData;

SerialPort CurrentPort = (SerialPort)sender; //// Int routine gave is this in the arguments

int LastByteInUartBuffer = CurrentPort.ReadBufferSize;
int TheNumberOfBytes = CurrentPort.BytesToRead;
byte[] inputData = new byte[TheNumberOfBytes];
int RenameThisInt = CurrentPort.Read(inputData, 0, TheNumberOfBytes);                 //// This is a C# property method of ports

int Dest;
Dest = UartPlaceHolders.RxBufferLeader; //// Will index into buffer for Chief dispatch

做一点鼠标悬停告诉我......

  • LastByteInUartBuffer 有 4096 个
  • TheNumberOfBytes 有 8092
  • RenameThisInt 有 8092 个
  • inputData 有正确的东西

(我知道串行端口另一端的数据是什么样的,因为我自己生成它们)

我阅读了 MSDN 网站上的这两页,ReadBufferSize 和 BytesToRead

任何人,请纠正我。如何从 4K 缓冲区中获取近 8K 字节?

【问题讨论】:

    标签: c# serial-port


    【解决方案1】:

    请注意SerialPort.ReadBufferSize Property 上的此注释:

    因为 ReadBufferSize 属性只代表 Windows 创建的缓冲区,它可以返回一个小于 BytesToRead 属性,表示 SerialPort 缓冲区和 Windows 创建的缓冲区。

    【讨论】:

    • 详情,天哪。那么,这两个缓冲区是什么?它们是连续的吗?它们能长到多大?我已经遇到过数据太多太快的问题。这可以进一步阐明以前神秘的行为。我不认为微软有一个页面来解释这些缓冲区是从哪里形成的,或者它们是如何增长的。顺便说一句,感谢您指出我错过了(我认为)我阅读的页面上的第二句话,从而向全世界展示了我是多么聪明。我不敢相信我错过了。不管怎么说,还是要谢谢你。谦逊是一种理想的性格特征。
    • 不用担心会误读文档——这种情况经常发生。但是为什么你需要知道 Windows 内部缓冲区的大小呢?难道你不能只读取可用的内容——或者你在中间缓冲区中有空间的内容——哪个更小——然后迭代直到没有更多吗?
    • @Internal Server 错误,我在一秒钟内连续 256 次发送 64 个字节的数据包。我必须解构它们,去掉协议开销,将 24 位有符号整数更改为 32 位有符号整数,然后将它们传递给一个类,该类将它们绘制成一堆线。在这种情况下,4096 字节的缓冲区确实帮了我一个忙。即,我一次可以处理 0.25 秒的数据;它几乎可以为我解决我的噩梦。现在缺少了一百个字节,好吧;合理的代码就这么多。
    • 您需要一个数据收集队列或其他东西,您可以在其中组装整个数据包(无论在您的上下文中意味着什么),并在您准备好完整数据包时将它们传递给您的其他逻辑。
    • 这是目前正在进行的方案。丑陋,但我没有更好的主意。哦,好吧,我们将协议定义为包含一个长度字节;然后当然是16位和倒退。我希望我能按小时获得报酬;比练习法律更好。 /非常感谢
    【解决方案2】:

    答案其实在ReadBufferSize的文档中:

    BytesToRead 属性可以返回一个大于 ReadBufferSize 属性的值,因为 ReadBufferSize 属性仅表示 Windows 创建的缓冲区,而 BytesToRead 属性表示除了 Windows 创建的缓冲区之外的 SerialPort 缓冲区。

    在这种情况下,“Windows 创建的缓冲区”是底层驱动程序内存,而不是由 C# SerialPort 对象分配的内存。

    【讨论】:

    • 谢谢,现在我知道了另一个秘密。我不禁注意到,另一个数字正好是 100 字节,比缓冲区大小的两倍小。因为我碰巧在每个小数据包中发送了 64 个字节的倍数,Grrr,这真的很烦人。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多