簡體   English   中英

.Net SerialPort Readline與DataReceived事件處理程序

[英].Net SerialPort Readline Vs DataReceived Event Handler

在VB.NET中,使用SerialPort.ReadLine()方法與使用DataReceived事件處理程序之間有什么區別? 當前,我正在使用接收到數據的事件處理程序並檢測行尾。 問題在於數據是成塊而不是1行句子。 如果我使用SerialPort.ReadLine()方法,則數據以1行句子的形式出現。 但是,使用此方法可以使用NewLine變量來設置端口的行結束符。 readline方法是否只是為我處理緩沖區? 不管使用哪種方法,數據是否仍然成塊出現?

方法1:

While _continue
    Try 
        Dim message As String = _serialPort.ReadLine()
        Console.WriteLine(message)
    Catch generatedExceptionName As TimeoutException
    End Try 
End While 

方法2:

Public Sub StartListener()
    Try

        _serialport = New SerialPort()
        With _serialport
            .PortName = "COM3"
            .BaudRate = 38400
            .DataBits = 8
            .Parity = Parity.None
            .StopBits = StopBits.One
            .Handshake = Handshake.None
            AddHandler .DataReceived, AddressOf DataReceivedHandler
        End With
        _serialport.Open()

    Catch ex As Exception
    End Try
End Sub

Private Shared buffer As String = ""

Private Sub DataReceivedHandler(sender As Object, e As SerialDataReceivedEventArgs)
    Try
        Dim rcv As String = _serialport.ReadExisting()
        buffer = String.Concat(buffer, rcv)

        Dim x As Integer
        Do
            x = buffer.IndexOf(vbCrLf)
            If x > -1 Then
                Console.WriteLine(buffer.Substring(0, x).Trim())
                buffer = buffer.Remove(0, x + 2)
            End If
        Loop Until x = -1
    Catch ex as Exception
    End Try
End Sub

我當前正在使用方法2,但正在考慮切換到方法1,因為它看起來更安全並且看上去更漂亮,但是有什么意義呢? 謝謝

您的ReadLine()調用是同步的,並且會阻塞您的代碼,從而有可能導致程序掛起。 DataReceived是異步的,而不是異步的。 這使它更難使用,沒有免費的午餐。 但是很重要,串行端口可能足夠慢,以致整個程序對用戶輸入無響應。 在控制台模式程序中或使用單獨的線程時,通常不會出現問題。

您也可以在DataReceived事件處理程序中調用ReadLine(),這很荒唐。 從技術上講,這可能導致死鎖,您應該使用ReadTimeout屬性。

但是,由於使用了控制台,因此幾乎沒有理由使用DataReceived。

使用.NET SerialPort實現時, 切勿嘗試使用DataReceived事件和任何其他方法從串行端口讀取。 ReadExistingReadLine都使用相同的基礎MemoryStream。 當事件中斷導致您嘗試讀取已經從流中刪除的數據時,您將遇到從ReadLine從MemoryStream提取數據的情況。

使用一種方法或另一種方法。 請勿同時使用。

關於ReadLine阻止您的UI線程,Hans Passant是正確的。 您有兩種解決方法:使用DataReceived事件; 或將處理SerialPort代碼放在單獨的線程上。

通常最好使用DataReceived事件,因為.NET將在工作線程上自動運行該事件。 但是,您失去了ReadLine的免費贈品。 而且,如果需要執行預讀操作(必須提供類似ReadLine功能的功能),則必須手動緩沖輸入。

暫無
暫無

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

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