title: VB.NET - Problem Reading Serial Port - " Waiting for Activation" Status
body: <p>I am new to Async, Await ,Task etc . </p>
  
  <p>I am sending a Ascii command string  to serial port and then  reading a 9 bytes returned as the measured value from the port . </p>
  
  <p>If the command  ( voltage measurement command ) is sent and received by the instrument it returns  9 bytes .  This is the normal case .  This works fine if there are 9 bytes to be read . </p>
  
  <p>However , if nothing is  returned because the command string did not transmit properly (most likely) and then the instrument does not return anything ,then instead of the 9 bytes expected nothing is read and Read.status is "Waiting for Activation"</p>
  
  <p>Now if i send the command again after the failed read event , then the measured value is not read properly . I get 5 bytes read instead of  the expected 9 bytes  or sometimes nothing is read </p>
  
  <p>I am  reading the port using </p>
  
  <p><code>Dim read = Port.BaseStream.ReadAsync(readback, readback.Length - bytesLeft, bytesLeft)</code></p>
  
  <p>Multiple read attempts  does not solve the problem  . It seems  <code>Port.BaseStream.ReadAsync()</code> latches in a particular state if the required no of bytes are not read and this is preserved until it is reset somehow . .I do not know how to reset it . </p>
  
  <p>How can I reset the state  of <code>Port.BaseStream.ReadAsync()</code> after a failed read event so that if i try to send the command again and  read the port again it will work normally ? </p>
  
  <p>Here is the <code>GetLoadVoltage</code> function code that sends the command and then calls the <code>ReadAllBytes</code> function to read back the measured value from the serial port . </p>
  
  <p>Any help or advice appreciated ! </p>
  
  <pre><code>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 &lt; 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 '
  </code></pre>
  
  <p>***************This is the Read Function  ************</p>
  
  <pre><code>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 &lt;&gt; 0
                  Dim read = Port.BaseStream.ReadAsync(readback, readback.Length - bytesLeft, bytesLeft)
                  Await Task.WhenAny(Task.Delay(5000), read)
  
                  While read.IsCompleted = False
                      If trys &lt; 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'
  </code></pre>