-
-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SerialPortDevice can hang when no data is written to COM port. #113
Comments
Also relevant reading. dotnet/runtime#28968 Seems like lots of people have trouble with the SerialStream class (internal to System.IO.SerialPort), and the [sparxeng] article link I posted earlier spells out a bunch of problems with the System.IO.SerialPort class in general. In the dotnet runtime issue 28968 thread, there is some preference to using background threads with synchronous APIs which ostensibly don't ignore the read timeouts? I see a couple of approaches for the NmeaParser library:
|
Yeah I'm finding that the CancellationToken and the ReadTimeout appear to be completely ignored in the read call. It causes issues like this one, as well as #111 |
@dotMorten i ended up creating a copy of your implementation of serial nmea device that uses RJCP's version of SerialPort. I have found that implementation is much more robust than system.io.ports.serialport and it was basically a drop in replacement. The .NET implementation seems to be pretty notorious and has been for a long time, I doubt they'll fix it anytime in the next decade, if at all. In your shoes, I don't know that I would take on that dependency for this repo unless you've vetted the RJCP implementation, but the workaround is honestly not the worst. |
@SonicScholar Cool. You shouldn't actually have to clone this library to do that. You can just create a subclass of NmeaDevice that returns the read stream in the abstract methods you must implement. |
I'd say feel free to close this ticket and offer the workaround to copy/paste your serial NMEA device class with one that can take a more robust implementation. Would it be worth putting in some compiler warning about how there are issues with the .NET version of serial port, and the recommendation would be to extend NmeaDevice if adverse behavior occurs? |
Another option would be to use the WinRT APIs instead. Just working on exposing that to net6.0-windows (it's already there in the UWP build) |
Yeah that's exactly what I did, worked great! |
I've added the WinRT based serial device that handles CloseAsync much better without getting hung. |
Here's a simple unit test I wrote that simulates what's happening with the Nmea and SerialPort device classes.
I believe an issue similar to #88 is in the latest NmeaParser 2.2.2 package from Nuget. (FWIW, I didn't see where the 2.2.2 tag/release was here). Also, this may be the same issue reported in #111 but not sure.
If you read this article, it might lead to believe that it's an issue with the serial port class that we wouldn't have any control over (other than working around it in the SerialPortDevice class somehow...) My suspicion from one of the comments is that the SerialPort class' internal stream provides a ReadAsync method (which is used in this NmeaParser library)- The ReadAsync calls BeginRead and EndRead internally. And BeginRead apparently sets the read timeout to infinity before putting it back to the user defined ReadTimeout during the read .
I am on .NET 8 and using the System.IO.Ports 8.0.0 NuGet package
I am game to talk about how a fix/workaround could be implemented for this.
Here's the code:
it's also important to note that COM1 did not have the GPS connected to it. I am playing around with implementing a kind of "COM port crawler" that's built on top of the NmeaParser lib layer. (I get that there are probably more efficient ways to do this.... but still I think this issue could arise for others, especially if the device on the other end is not writing data to the stream)
p.s. this library is awesome!!
The text was updated successfully, but these errors were encountered: