SerialPort.BaseStream.ReadAsync drops or scrambles bytes when reading from a USB Serial Port

假装没事ソ 提交于 2019-11-30 07:38:10

I finally came up with an answer after stepping through the decompiled source code for the .Net SerialPort class (with resharper installed just Rclick on SerialPort->Navigate->Decompiled Sources).

Answer #1: The bytes out of order problem was due to an error earlier in my program. I had canceled and restarted the readAsync loop, but I was using the wrong cancellation token so there were two copies of the loop both awaiting readAsync from the serial port. Both were issuing interrupts to return the received data, but of course it was a race condition as to which one got there first.

Answer #2: Note the way I am using the synchronous read method: I don't use the Received event (which doesn't work correctly) or check the number of bytes to read (which is unreliable) or anything like that. I merely set a timeout of zero, attempt to read with a large buffer, and check how many bytes I got back.

When called in this way, the synchronous SerialPort.Read first attempts to fulfill a read request from an internal cache[1024] of data bytes received. If it still doesn't have enough data to meet the request, it then issues a ReadAsync request against the underlying BaseStream using the exact same buffer, (adjusted)offset, and (adjusted)count.

Bottom line: When used the way I am using it, the synchronous SerialPort.Read method behaves exactly like SerialPort.ReadAsync. I conclude that it would probably be fine to put an async wrapper around the synchronous method, and just await it. However, I don't need to do that now that I can read from the basestream reliably.

Update: I now reliably receive more than 3Mbps from my serial port using a Task containing a loop that continuously awaits SerialPort.Basestream.ReadAsync and adds the results to a circular buffer.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!