连续读取和解析串行数据的快速方法
Fast approach to read and parse serial-data continuously
我有一个线程来读取和解析串行数据。
消息采用二进制格式,并以字符 'F'、'S'、'Q' 或 'M' 开头。
没有换行符,也没有特殊的结束字符(上面的字符表示一条消息已完成,并且准备好解析之前的所有内容)。
如何持续读取和解析数据?
我想到的就是拥有一个 4096 字节长的输入缓冲区(字节数组),然后按照以下过程操作:
- 手动跟踪缓冲区中的位置
- 通过
SerialPort.Read(buffer, position, byteCount)
添加可用数据
- 尝试从缓冲区中解析尽可能多的消息
- 将其余部分复制到临时缓冲区
- 重置输入缓冲区
- 将临时缓冲区的内容复制到原始缓冲区
- 设置缓冲区中的位置
你能想到更快/更简单的方法吗?
获得一些使用 SerialPort C# 组件的经验后
开头:独占一个串口。
然后:
第一个并行任务:在 常规 之后继续读取 整个 缓冲区内容
间隔并将读取的块推送到数据的 "Gathering Collection" 中。
第二个并行任务:分析 "Gathering Collection" 以获得已完成的 "phrase",委托克隆的 "phrase" 到 "Phrase Manager" 并从 "Gathering Collection"[=46= 中排除短语]
您可以自由实施 "Gathering Collection",但对我来说重要的是:
读取全部,但不是来自串行端口缓冲区的大小内容
为了避免损失并在消息中保存订单构建您自己的端口调度程序而不是让任何人随时打开和关闭您的端口 reading/writing.
通过实验检测端口读取频率。更频繁的读取操作将使您的代码检测到 fatser a "phrase" 并启动 proder handlind。在未检测到 "phrase" 的情况下过于频繁地读取可能会消耗额外的资源。
获得成功的一个非常简单的方法是停止尝试让它变得更快。没有意义,串行端口数据速率非常非常低,而现代计算机非常非常快。您的 Read()
只调用 returns 一个字节,很少调用 2.
请注意,这很难看到,当您调试并单步执行代码时,您会人为地大大降低程序速度。允许接收更多字节,因此 Read()
调用返回更多字节。但是当程序以正常速度运行时不会出现这种情况。
所以改用SerialPort.BaseStream.ReadByte()
。使代码非常简单。
我有一个线程来读取和解析串行数据。 消息采用二进制格式,并以字符 'F'、'S'、'Q' 或 'M' 开头。 没有换行符,也没有特殊的结束字符(上面的字符表示一条消息已完成,并且准备好解析之前的所有内容)。
如何持续读取和解析数据?
我想到的就是拥有一个 4096 字节长的输入缓冲区(字节数组),然后按照以下过程操作:
- 手动跟踪缓冲区中的位置
- 通过
SerialPort.Read(buffer, position, byteCount)
添加可用数据 - 尝试从缓冲区中解析尽可能多的消息
- 将其余部分复制到临时缓冲区
- 重置输入缓冲区
- 将临时缓冲区的内容复制到原始缓冲区
- 设置缓冲区中的位置
你能想到更快/更简单的方法吗?
获得一些使用 SerialPort C# 组件的经验后
开头:独占一个串口。
然后:
第一个并行任务:在 常规 之后继续读取 整个 缓冲区内容 间隔并将读取的块推送到数据的 "Gathering Collection" 中。
第二个并行任务:分析 "Gathering Collection" 以获得已完成的 "phrase",委托克隆的 "phrase" 到 "Phrase Manager" 并从 "Gathering Collection"[=46= 中排除短语]
您可以自由实施 "Gathering Collection",但对我来说重要的是:
读取全部,但不是来自串行端口缓冲区的大小内容
为了避免损失并在消息中保存订单构建您自己的端口调度程序而不是让任何人随时打开和关闭您的端口 reading/writing.
通过实验检测端口读取频率。更频繁的读取操作将使您的代码检测到 fatser a "phrase" 并启动 proder handlind。在未检测到 "phrase" 的情况下过于频繁地读取可能会消耗额外的资源。
获得成功的一个非常简单的方法是停止尝试让它变得更快。没有意义,串行端口数据速率非常非常低,而现代计算机非常非常快。您的 Read()
只调用 returns 一个字节,很少调用 2.
请注意,这很难看到,当您调试并单步执行代码时,您会人为地大大降低程序速度。允许接收更多字节,因此 Read()
调用返回更多字节。但是当程序以正常速度运行时不会出现这种情况。
所以改用SerialPort.BaseStream.ReadByte()
。使代码非常简单。