Будет ли событие SerialPort DataReceived вызываться повторно? - PullRequest
2 голосов
/ 16 мая 2010

Предположим, я читаю данные из SerialPort всякий раз, когда доступно 100 байт, иначе ничего не делается. Это означает, что оставшиеся данные будут по-прежнему доступны в буфере SerialPort. Это чтение выполняется внутри обработчика событий DataReceived.

Теперь предположим, что возникает ситуация, когда там, скажем, 50 байтов в буфере SerilaPort, и больше не поступает никаких данных. Насколько я понимаю, событие DataReceived будет запускаться всякий раз, когда имеется определенное количество байтов, доступных для чтения из буфера.

Теперь, в данном сценарии, если я никогда не прочитаю эти 50 байтов, будет ли событие активироваться непрерывно из-за наличия этих непрочитанных байтов?

Ответы [ 3 ]

3 голосов
/ 18 мая 2010

Я опубликовал ответ (см. Комментарии выше). Это в документации. «... когда данные получены из объекта SerialPort.» ОП сказал: «Если я никогда не прочитаю эти 50 байтов, будет ли событие активироваться непрерывно из-за наличия этих непрочитанных байтов?» и вы ответили: «Да, он будет продолжать стрелять, пока вы не вызовете Read ()»

Событие срабатывает только при получении новых данных. Если вы не обработаете этот фрагмент данных, этот фрагмент данных НЕ будет вызывать новое событие. Однако, если поступают новые данные, запускается новое событие, и вы можете обработать все это.

3 голосов
/ 16 мая 2010

Да, он будет срабатывать при поступлении дополнительных байтов, пока вы не вызовете Read (). Вы можете использовать свойство ReceivedBytesThreshold, чтобы задержать это. Обычно это плохая идея, потеря байта из-за ошибки переполнения может привести к полному захвату связи. Буферизируйте то, что вы читаете () в обработчике событий самостоятельно.

Также помните, что это только известное поведение драйвера последовательного порта Microsoft. Класс SerialPort использует функцию API WaitCommEvent, это зависит от драйвера, чтобы реализовать это. Особенно много драйверов USB, которые эмулируют последовательный порт для облегчения взаимодействия с пользовательским устройством, не созданы равными.

0 голосов
/ 18 мая 2010

Я думаю, это подтверждает мою точку зрения, извините за код VB.

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

Отладочный вывод

 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
...