.Net SerialPort Readline 与 DataReceived 事件处理程序

.Net SerialPort Readline Vs DataReceived Event Handler(.Net SerialPort Readline 与 DataReceived 事件处理程序)

本文介绍了.Net SerialPort Readline 与 DataReceived 事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 VB.NET 中,使用 SerialPort.ReadLine() 方法与使用 DataReceived 事件处理程序有什么区别?目前,我正在使用数据接收事件处理程序并检测行尾.问题是数据以块的形式出现,而不是 1 行句子.如果我使用 SerialPort.ReadLine() 方法,则数据包含 1 行句子.然而,使用这种方法,有 NewLine 变量来设置端口的行结束字符.readline 方法是否只是为我处理缓冲区?无论使用何种方法,数据是否仍以块的形式出现?

In VB.NET, what is the difference between using the SerialPort.ReadLine() method versus using the DataReceived event handler? Currently, I'm using the data received event handler and detecting the line endings. The problem is the data is coming in chunks and not 1 line sentences. If I use SerialPort.ReadLine() method, the data comes in 1 line sentences. Using this method, however, has the NewLine variable to set the line ending character for the port. Is the readline method just handling the buffer for me? Does the data still come in chunks regardless of the method used?

方法一:

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

方法二:

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,因为它看起来更安全,看起来更漂亮,但有什么意义呢?谢谢

I am currently using Method 2, but was thinking about switching to Method 1 because it seems safer and looks prettier you know, but what's the point? Thanks

推荐答案

在使用 .NET SerialPort 实现时,您应该不要尝试从串口读取使用 DataReceived 事件和任何其他方法.ReadExistingReadLine 都使用相同的底层 MemoryStream.当事件中断导致您尝试读取已从流中删除的数据时,您将遇到从 ReadLine 中拉出 MemoryStream 数据的情况.

When working with the .NET SerialPort implementation, you should NEVER try to read from the serial port using the DataReceived event and any other method. ReadExisting and ReadLine both use the same underlying MemoryStream. You will run into situations where you are pulling data off the MemoryStream from the ReadLine when the event interrupts causing you to attempt to read data that has already been removed from the stream.

使用一种方法或另一种方法.两者都不要使用.

Use one method or the other. Do no use both.

Hans Passant 关于 ReadLine 阻塞您的 UI 线程是正确的.您有两种方法:使用 DataReceived 事件;或将处理 SerialPort 的代码放在单独的线程上.

Hans Passant is correct about the ReadLine blocking your UI thread. You have two methods around that: use the DataReceived event; or place your code that handles the SerialPort on a separate thread.

使用 DataReceived 事件通常更可取,因为 .NET 会自动在工作线程上运行该事件.但是,您会失去 ReadLine 的免费赠品.如果您需要执行预读(为您提供类似 ReadLine 功能),您必须手动缓冲输入.

Using the DataReceived event is usually preferable as .NET will run that on a worker thread automatically. You lose the freebie of the ReadLine though. And you have to manually buffer the input if you need to perform read aheads (to give you something like the ReadLine functionality).

这篇关于.Net SerialPort Readline 与 DataReceived 事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:.Net SerialPort Readline 与 DataReceived 事件处理程序

基础教程推荐