VB.NET-读取串行端口时出现问题-“等待激活”状态

时间:2019-02-14 13:51:28

标签: .net vb.net asynchronous

我是异步,等待,任务等的新手。

我正在将Ascii命令字符串发送到串行端口,然后从端口读取作为测量值返回的9个字节。

如果仪器发送和接收了命令(电压测量命令),它将返回9个字节。这是正常情况。如果要读取9个字节,则此方法很好。

但是,如果由于命令字符串未正确传输(最有可能)而未返回任何内容,则仪器未返回任何内容,则不是9个字节,而是预期未读取任何内容,并且Read.status为“正在等待激活”

现在,如果我在读取失败事件之后再次发送命令,则无法正确读取测量值。我读取了5个字节,而不是预期的9个字节,或者有时什么也不读取

我正在使用

读取端口

Dim read = Port.BaseStream.ReadAsync(readback,readback.Length-bytesLeft,bytesLeft)

多次读取无法解决问题。如果未读取所需的字节数,则Port.BaseStream.ReadAsync()似乎会处于特定状态,并且将保留该状态,直到以某种方式将其重置为止。我不知道如何重设它。

如何在失败的读取事件后重置Port.BaseStream.ReadAsync()的状态,以便如果我尝试再次发送命令并再次读取端口,它将正常工作?

这里是GetLoadVoltage函数代码,该函数代码发送命令,然后调用ReadAllBytes函数从串行端口读取测量值。

任何帮助或建议,不胜感激!

Async Function GetLoadVoltage(address As UInt16, channel As UInt16, cancelToken As Threading.CancellationToken) As Task(Of Double) Implements ILoadComms.GetLoadVoltage

Try
            'Variables and Set-Up
            Dim trys = 0

            Dim command1 As Byte() =
               System.Text.Encoding.ASCII.GetBytes("@" + 
               address.ToString("00") + "L" + channel.ToString("0") + "V?")


            Await TimeLimitedWrite(command1)

            Dim readback1 = Await ReadAllBytes(9, cancelToken)


            cancelToken.ThrowIfCancellationRequested()

            Dim adrs As String = address.ToString("00")
            Dim pattern As String = adrs + ":\d{3}\.\d{1}"
            Dim input As String = 
            Text.Encoding.ASCII.GetString(readback1).Replace(vbCr, "")

            Dim m As Match = Regex.Match(input, pattern, 
            RegexOptions.IgnoreCase)

            If m.Success Then
                Return CDbl(System.Text.Encoding.ASCII.GetString(readback1, 
                3, 5))
            Else
                While m.Success = False
                    If trys < 5 Then
                        StarPrint("Corrupted string " + input, _logs)
                        StarPrint("GetLoadVoltage Retry " + trys.ToString, 
                        _logs)
                        trys = trys + 1
                        command1 =
                        System.Text.Encoding.ASCII.GetBytes("@" + 
                        address.ToString("00") +"L" + channel.ToString("0") 
                        + "V?")
                        Await TimeLimitedWrite(command1)
                        readback1 = Await ReadAllBytes(9, cancelToken)
                        input = 
                      Text.Encoding.ASCII.GetString(readback1).Replace(vbCr, 
                       "")
                        m = Regex.Match(input, pattern, 
                        RegexOptions.IgnoreCase)
                    Else
                        Throw New CommsInvalidException("GetLoadVotage(): 
                        Format exception 1")
                    End If
                End While
                Return CDbl(System.Text.Encoding.ASCII.GetString(readback1, 
               3, 5))
            End If
        Catch cancelEx As OperationCanceledException
            Throw
        Catch ex As Exception
            Throw
        End Try
    End Function '

***************这是读取功能************

Protected Async Function ReadAllBytes(expectedBytes As Integer, cancelToken As Threading.CancellationToken) As Task(Of Byte())

Try
            Dim trys = 0
            Dim readback(expectedBytes - 1) As Byte
            Dim bytesLeft = expectedBytes

            readWatch.Reset()
            readWatch.Start()

            While bytesLeft <> 0
                Dim read = Port.BaseStream.ReadAsync(readback, readback.Length - bytesLeft, bytesLeft)
                Await Task.WhenAny(Task.Delay(5000), read)

                While read.IsCompleted = False
                    If trys < 5 Then
                        _logs.PrintToDebug("Read all bytes RETRY : " + trys.ToString)
                        trys = trys + 1
                        read = Port.BaseStream.ReadAsync(readback, readback.Length - bytesLeft, bytesLeft)
                        Await Task.WhenAny(Task.Delay(3000), read)

                    Else

                        ' If (Flagged.Contains(Port.PortName)) Then
                        'Flagged.Remove(Port.PortName)
                        'End If
                        'Return readback

                        Throw New CommsReadTimeoutException("ReadAsync Timed Out trying to read " +                 expectedBytes.ToString() + " Bytes")
                    End If
                End While

                bytesLeft = bytesLeft - read.Result
            End While

            If (Flagged.Contains(Port.PortName)) Then
                Flagged.Remove(Port.PortName)
            End If

            readWatch.Stop()
            Dim format As String = "{0,-10} {1,-5} {2, -10} {3, -10}"
            Dim rdBk As String = Text.Encoding.ASCII.GetString(readback).Replace(vbCr, "")
            Dim Milli As String = "Ms: " + readWatch.ElapsedMilliseconds.ToString ' Ms for milliseconds
            Dim PrtNme As String = Port.PortName
            Dim rd As String = "READ"
            _logs.PrintToDebug(String.Format(format, Milli, PrtNme, rd, rdBk))

            cancelToken.ThrowIfCancellationRequested()
            Return readback
        Catch ex As InvalidOperationException
            _logs.PrintToDebug("ReadAsync Eror trying to read")
            Throw New InvalidOperationException("ReadAsync Error: " + ex.Message, ex)
        Catch ex As CommsReadTimeoutException
            _logs.PrintToDebug(ex.Message)


            Throw
        End Try
    End Function'

0 个答案:

没有答案