I am reading data sent to a serial port (that is, COM3) using code like this:
_serialPort.PortName = "COM3";
_serialPort.BaudRate = 9600;
_serialPort.Parity = Parity.None;
_serialPort.DataBits = 8;
_serialPort.StopBits = StopBits.One;
_serialPort.ReadTimeout = 500;
_serialPort.WriteTimeout = 500;
_serialPort.DataReceived += new SerialDataReceivedEventHandler(_serialPort_DataReceived);
_serialPort.Open();
The data coming from that serial port are commands and can be a string of any length ending in '\0'. I'm looking for best practices on how to efficiently read such data. I'm thinking a producer/consumer pattern might be best, where:
- Every time the DataReceived event fires, I read the string from the port and append to a stringbuffer or some other structure
- I then have another thread that constantly inspects the stringbuffer or structure for char '\0' and if found, parses the and remove the command string.
Would this be the most efficient way to handle this? Is there any sort of blocking serial read function that doesn't rely on the dataReceived event?
I have found that the
dataReceieved
event can fire too often and does block theSerialPort
when code is running in the event. You say you might want this functionality but here is more information that might or might not be useful.I use a
Timer
, often at 10 Hz. In theTimer
, I checkSerialPort.BytesToRead > 0
. Then I useSerialPort.ReadLine
which reads one line of text and saves a lot of code to processes the inbound buffer.If you
Loop
untilBytesToRead == 0
, reading each line either into a buffer for later processing or process directly after the read.The
ReadTimeout
property in your example is useful if you know how long it takes the Arduino to construct a line of text and will cause anException
if only part of a line is received within theReadTimeout
.