views:

464

answers:

3

Suppose I read data from SerialPort whenever there is 100 bytes available or else nothing is done. That means, the remaining data will still be available in the SerialPort Buffer. This reading is done inside the event handler of DataReceived.

Now suppose a situation arises, when there there is, say 50 bytes in the SerilaPort Buffer and no more data comes. From what I understand, the DataReceived Event will be triggered whenever there is certain amount of bytes available for reading from the Buffer.

Now, in the given scenario, if I never read those 50 bytes, will the Event get activated continuously due to the presence of these unread bytes?

+1  A: 

Yes, it will keep firing when additional bytes come in until you call Read(). You could use the ReceivedBytesThreshold property to delay that. This is usually a bad idea, losing a byte due to an overrun error could cause communications to seize completely. Buffer what you Read() in the event handler yourself.

Also beware that this is only the known behavior of the Microsoft serial port driver. The SerialPort class uses the WaitCommEvent API function, it is up to the driver to implement this. Especially the plethora of USB drivers that emulate a serial port to make it easy to interface to a custom device are not created equal.

Hans Passant
Ok. So to track arrival of fresh data, I must do so by other means instead of relying on the event being triggered to indicate fresh data?
Gunner
Erm, no, it fires when there are new bytes available to read. Fresh ones. They only turn stale when you don't read.
Hans Passant
But does this not contradict your earlier answer?Perhaps I am misunderstanding..What do you imply by "turn stale"?
Gunner
I don't think so. To remove all confusion, you *always* read the number of BytesToRead in the event, there's no point in reading less. Which means that when the event fires again, you get *fresh* bytes.
Hans Passant
No. Whether or not it is good policy is another discussion.
dbasnett
How can the wrong answer be checked? The event only fires when there is new data. If you reach a point where new data is not arriving, the event will not fire.
dbasnett
Just last week we had this discussion on Meta of how the more points you have the more likely the wrong answer will be accepted.
dbasnett
@dbasnett: come on man, if you know the proper answer it behooves you to post it. Your "this answer is from another high rate answer, must thus be wrong" analysis" is leaky, nowhere was it stated that the event fires when there's no data. Don't be a downvoting luzer, post.
Hans Passant
From the OP - "Now, in the given scenario, if I never read those 50 bytes, will the Event get activated continuously due to the presence of these unread bytes?" Hans answer - "Yes, it will keep firing until you call Read()." What I said - "The event only fires when there is new data. If you reach a point where new data is not arriving, the event will not fire."
dbasnett
A: 

I did post the answer(see comments above). It is in the documentation. " ...when data is received from the SerialPort object." The OP said "if I never read those 50 bytes, will the Event get activated continuously due to the presence of these unread bytes?" and you replied "Yes, it will keep firing until you call Read()."

The event only fires whenever new data is received. If you do not process that piece of data, that piece of data will NOT cause a new event. However, if new data arrives, a new event will fire and you can then process it all.

@hans - don't tell me what to do.

dbasnett
"To remove all confusion, you always read the number of BytesToRead in the event, there's no point in reading less. Which means that when the event fires again, you get fresh bytes." That is your opinion. What happens if more bytes arrive while you are reading bytes in the event? Test I have done at .75 Mbps show that does occur.
dbasnett
Ok guys, thanks for the help :)But please, let's be bit more professional. We can work towards proving our or disprove someone else's point, but starting a flame war isn't a cool thing.
Gunner
+1  A: 

I think this proves my point, sorry for the VB Code.

Private Sub Button1_Click(ByVal sender As System.Object, _
                          ByVal e As System.EventArgs) _
                          Handles Button1.Click
    'set up the com port for a test
    SerialPort1.PortName = "COM5" 'attached to breakout box with loopback
    SerialPort1.BaudRate = 115200 'some speed
    SerialPort1.Encoding = System.Text.Encoding.GetEncoding("windows-1252")
    Dim b() As Byte = New Byte() {42, 16, 20, 254, 255, 128} 'test data

    ctrcv = 0 'counter
    SerialPort1.Open() 'open the port
    Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss.ffff")) 'show time
    SerialPort1.Write(b, 0, b.Length) 'write the test data

    'give the DataReceived event handler chances to fire
    Threading.Thread.Sleep(30000)

    'show the last time it fired and how many times
    Debug.WriteLine(lastRCV.ToString("HH:mm:ss.ffff") & " " & ctrcv)
    'show how many are available to read
    Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss.ffff") & " " & SerialPort1.BytesToRead)
    Array.Clear(b, 0, b.Length)
    SerialPort1.Read(b, 0, SerialPort1.BytesToRead) 'read them

    SerialPort1.Close() 'close the port
    Stop
End Sub
Dim ctrcv As Integer = 0, lastRCV As DateTime
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, _
                                     ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
                                     Handles SerialPort1.DataReceived
    ctrcv += 1
    lastRCV = DateTime.Now
End Sub

Debug output

 09:34:11.3241 <- when the test started
 09:34:11.3642 3 <- the last data received event!, and how many events
 09:34:41.3718 6 <- when the test ended
dbasnett
@Hans Passant - Does this work differently in C?
dbasnett