Low Latency Serial Communications In .Net
I have been researching various third party libraries and approaches to low latency serial communications in .Net. I've read enough that I have now come full circle and know as little as I did when I started due to the variety of conflicting opinions.
For example, the functionality in the Framework was ruled out due to some convincing articles stating: "that the Microsoft provided solution has not been stable across framework versions and is lacking in functionality."
I have found articles bashing many of the older COM bas开发者_StackOverflowed libraries. I have found articles bashing the idea of a low latency .Net app as a whole due to garbage collection.
I have also read articles demonstrating how P/Invoking Windows API functionality for the purpose of low latency communication is unacceptable.
THIS RULES OUT JUST ABOUT ANY APPROACH I CAN THINK OF!
I would really appreciate some words from those with been there / done that experience. Ideally, I could locate a solid library / partner and not have to build the communications library myself. I have the following simple objectives:
- Sustained low latency serial communication in C# / VB.Net
- 32/64 bit
- Well documented (if the solution is 3rd party)
- Relatively unimpacted (communication and latency wise) by garbage collection .
- Flexible (I have no idea what I will have to interface with in the future!) The only requirement that I have for certain is that I need to be able to interface with many different industrial devices such as RS485 based linear actuators, serial / microcontroller based gauges, and ModBus (also RS485) devices.
Any comments, ideas, thoughts or links to articles that may iron out my confusion are much appreciated!
Latency is a non-issue on modern machines. Serial ports are glacially slow, 19.2 kilobaud is peanuts, the .NET SerialPort class handles them fine. The DataReceived event is delivered asynchronously by a threadpool thread that performs a blocking wait with WaitCommEvent(), you can't go faster than that.
I have a .NET Application that runs on a server with 16 COM ports, about 11 of which are currently connected to various devices, some RS485, many RS-232. (Diagram here: http://blog.abodit.com/2010/03/home-automation-block-diagram/). Most of these devices are running just 9600 baud, and most don't have very tight timing requirements. I have a thread per device handling receiving and while it runs at normal thread priority, all other non-communication threads run at a lower priority (as you should do for most background tasks anyway). I have had no issues with this setup. And, BTW it also plays music on three sound cards at the same time using high-priority threads from managed code and 1second DSound buffers, all without glitching.
So how tight are your latency requirements, what baud rate and how many serial ports are you trying to serve? The buffer on your UART at most normal baud rates is more than sufficient for garbage collection and much more to delay taking the next byte off it.
GC is not as evil as it is made out to be. On a properly prioritized threaded system with good management of object sizes and lifetimes and sufficient buffering (UARTS/Sound buffers etc.) it can perform very well. Microsoft is also continuously improving it and the .NET Framework 4 now provides background garbage collection. This feature replaces concurrent garbage collection in previous versions and provides better performance. See MSDN.
.NET is generally a poor choice for the kind of application you describe. This kind of thing is going to require native code and a language like C++ for at least the portion that requires low-latency.
Personally I love my BBUSB interface. When switched to bitbang mode it allows you direct on/off control 8 pins which you can set to be input or output.
"But I need a serial port." You say. It's entirely possible. Simply wire up the pins to a 9 pin male serial port and you're good to go.
The .Net Serial Port Class Consumes far too much CPU when sending receiving small packets at high frequencies. It also seems to miss some events. Since I needed to beable to send and receive 16 byte packets 1000 timesper seond reliably I wound up putting together something based off of the Windows API and can now easily fire 1000 small packets per second while consuming next to no CPU. I tried nearly every library available library, and fr this simple task, they all failed due to excessive CPU utilization or missed events.
精彩评论