簡體   English   中英

串行端口數據接收事件會重復觸發嗎?

[英]Will SerialPort DataReceived Event trigger repeatedly?

假設只要有100字節可用,否則我將從SerialPort讀取數據,否則什么也沒做。 這意味着,其余數據仍將在SerialPort緩沖區中可用。 該讀取是在DataReceived的事件處理程序內部完成的。

現在,假設出現一種情況,例如,SerilaPort緩沖區中有50個字節,而沒有更多數據到來。 據我了解,只要有一定數量的字節可用於從Buffer中讀取,就會觸發DataReceived事件。

現在,在給定的情況下,如果我從不讀取這50個字節,由於這些未讀取的字節的存在,事件是否將被連續激活?

是的,它將在其他字節進入時繼續觸發,直到您調用Read()為止。 您可以使用ReceivedBytesThreshold屬性來延遲該操作。 這通常是一個壞主意,由於溢出錯誤而丟失字節可能會導致通信完全被占用。 自己在事件處理程序中緩沖您讀取的內容。

還要注意,這只是Microsoft串行端口驅動程序的已知行為。 SerialPort類使用WaitCommEvent API函數,這取決於驅動程序來實現。 特別是模擬串行端口以使其易於連接到自定義設備的大量USB驅動程序並非一成不變。

我確實發布了答案(請參閱上面的評論)。 它在文檔中。 “ ...當從SerialPort對象接收到數據時。” OP說:“如果我從不讀取這50個字節,由於這些未讀取字節的存在,事件是否將被連續激活?” 您回答“是的,它將一直觸發直到您調用Read()為止。”

僅在收到新數據時才觸發該事件。 如果您不處理該數據,則該數據將不會導致新事件。 但是,如果有新數據到達,則將觸發一個新事件,然后您可以處理所有事件。

我認為這證明了我的觀點,對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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM