Можно ли надежно восстановить с IOException последовательного порта? - PullRequest
0 голосов
/ 19 мая 2018

Я использую службу Windows, которая проверяет аппаратный инструмент примерно пятнадцать раз в секунду, 24/7, на COM4.Когда прибор получает команду, он отвечает соответствующим образом, заканчивая свой ответ >CRLF, чтобы указать завершение кругового обхода.

Следующий код вызывает у меня некоторые проблемы:

01    Public Async Function SendAsync() As Task(Of Response)
02       Dim oResponse As Response
03       Dim sData As String
04 
05       Do
06         Me.Port.WriteLine(Me.Instruction)
07 
08         sData = Await ReadResponseAsync()
09         oResponse = New Response(Me.Instruction, sData)
10       Loop While oResponse.Status = Response.States.SyntaxError
11 
12       Return oResponse
13    End Function
14 
15    Private Async Function ReadResponseAsync() As Task(Of String)
16       Dim iSize As Integer
17       Dim sData As String
18       Dim aData As Byte()
19 
20       aData = New Byte(255) {}
21       sData = String.Empty
22 
23       Do
24         iSize = Await Me.Port.BaseStream.ReadAsync(aData, 0, aData.Length)
25         sData &= Encoding.ASCII.GetString(aData, 0, iSize)
26       Loop While Not sData.EndsWith($">{vbCrLf}")
27 
28       Return sData
29    End Function

I'mполучение редкого IOException в строке 24:

System.IO.IOException: операция ввода-вывода была прервана из-за выхода из потока или запроса приложения.

Это происходило дважды за последние 144 часа, что дает отношение 1 к примерно 3,8 мм циклам вызова / ответа.Это не соответствует никаким действиям по остановке службы.

Означает ли это, что данные для этого цикла навсегда потеряны для меня?

Если бы я должен был обернуть вызов ReadAsync() в Try/ Catch, вот так, будет ли следующий цикл воспринимать ожидающий ответ?

Do
  Try
    iSize = Await Me.Port.BaseStream.ReadAsync(aData, 0, aData.Length)
    sData &= Encoding.ASCII.GetString(aData, 0, iSize)

  Catch ex As IOException
    Main.Logger.Warn("IOException was skipped. Data will be retrieved on next attempt.")

    aData = New Byte(255) {}
    sData = String.Empty

  End Try
Loop While Not sData.EndsWith($">{vbCrLf}")

Я бы хотел ускорить тест для этого, но я не могу воспроизвести IOException в контексте.

...