SerialPort class DataReceived event question
-
In my current C# project, I am using an instance of the SerialPort class. I wanted to examine each character as it came in, so I registered a handler for the DataReceived event and set the ReceivedBytesThreshold property to 1. With these settings, I expected that the event handler would be called for each character received but I find that it only gets called once for every 5-8 characters. This is good for communication efficiency, but for what I want to do, I have to loop through the received characters in my event handler. Does anybody know if this is the expected behavior of this class?
-
In my current C# project, I am using an instance of the SerialPort class. I wanted to examine each character as it came in, so I registered a handler for the DataReceived event and set the ReceivedBytesThreshold property to 1. With these settings, I expected that the event handler would be called for each character received but I find that it only gets called once for every 5-8 characters. This is good for communication efficiency, but for what I want to do, I have to loop through the received characters in my event handler. Does anybody know if this is the expected behavior of this class?
-
-
In my current C# project, I am using an instance of the SerialPort class. I wanted to examine each character as it came in, so I registered a handler for the DataReceived event and set the ReceivedBytesThreshold property to 1. With these settings, I expected that the event handler would be called for each character received but I find that it only gets called once for every 5-8 characters. This is good for communication efficiency, but for what I want to do, I have to loop through the received characters in my event handler. Does anybody know if this is the expected behavior of this class?
I am not surprised, asynchronous receive is a complex process, there are several actors, and some buffers with their sizes and thresholds, some of which one cannot control at all. You should not be lazy and refuse to loop over the bytes you get in one go, that is pretty easy to accomplish. It gets really nasty when you have to implement a message-oriented protocol, where the sender sends two or more messages back-to-back, and your receiver unfortunately receives three or more DataReceived events, each covering an arbitrary part of the messages sent (say first half of first msg, then second half+first half of second msg, finally second half of second message). The only serial receive that goes smoothly is the one that has a fixed message separator (say a NEWLINE) which is guaranteed to appear in between messages and never inside a message (in that case set the NewLine property and use ReadLine). If that is not the case, get ready to collect what you get, whatever amount comes in, then re-packetize it according to your needs. And then, you should carefully consider whether you need some recovery mechanism, something that helps you out in case some character gets damaged or lost... :)
Luc Pattyn [My Articles] Nil Volentibus Arduum
-
I am not surprised, asynchronous receive is a complex process, there are several actors, and some buffers with their sizes and thresholds, some of which one cannot control at all. You should not be lazy and refuse to loop over the bytes you get in one go, that is pretty easy to accomplish. It gets really nasty when you have to implement a message-oriented protocol, where the sender sends two or more messages back-to-back, and your receiver unfortunately receives three or more DataReceived events, each covering an arbitrary part of the messages sent (say first half of first msg, then second half+first half of second msg, finally second half of second message). The only serial receive that goes smoothly is the one that has a fixed message separator (say a NEWLINE) which is guaranteed to appear in between messages and never inside a message (in that case set the NewLine property and use ReadLine). If that is not the case, get ready to collect what you get, whatever amount comes in, then re-packetize it according to your needs. And then, you should carefully consider whether you need some recovery mechanism, something that helps you out in case some character gets damaged or lost... :)
Luc Pattyn [My Articles] Nil Volentibus Arduum
I am quite familiar with the intricacies of communication code. I have written a number of serial drivers for embedded systems over the past 20 years or so. My use of C# has been limited to writing "quick & dirty" utilities for testing my embedded systems. In this case, my code was working fine - I was just seeking a better understanding of the SerialPort class which did not behave as I expected and the Microsoft documentation for it is shallow at best.
-- Regards, Ken I AM