As I've encountered an advice not to use the SerialPort.DataReceived event, nor the BytesToRead() (www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport), I am trying to implement a reader from a serial port with BeginRead & End Read. When the application reached the line:
Dim numBytesRead As Integer = Me._stream.EndRead(ar)
the following exception occurs:
System.IO.IOException: The I/O operation has been aborted because of either a thread exit or an application request.
at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
at System.IO.Ports.SerialStream.EndRead(IAsyncResult asyncResult)
at X_SerialComm.CSerialCommMng.ReadCallback(IAsyncResult ar)
That's where I need your assistance.
Thanks for any advice,
Amir
The full code:
Imports System.IO
Imports System.IO.Ports
Public Class CSerialCommMng
Public WithEvents m_port As SerialPort
Private _readBuffer(20000) As Byte
Private _stream As Stream
Public Sub New(pName As String)
Try
m_portName = pName
If m_port IsNot Nothing Then
If m_port.IsOpen Then
ClosePort()
End If
m_port = Nothing
End If
m_port = New SerialPort(pName)
_stream = m_port.BaseStream
SetPortAttrb()
Catch ex As Exception
RaiseEvent PortDoesNotExists(m_portName)
m_portName = ""
End Try
End Sub
Public Function Open() As Boolean
If m_port Is Nothing Then
RaiseEvent PortClosed()
Return False
End If
If m_port.IsOpen Then Return True
With m_port
GC.SuppressFinalize(m_port)
.Open()
Thread.Sleep(10)
GC.SuppressFinalize(.BaseStream)
End With
ReadFromSerial()
Return True
End Function
Private Sub ReadFromSerial()
Dim response As New CommsResponse()
Me._stream.BeginRead(Me._readBuffer, 0, Me._readBuffer.Length, New AsyncCallback(AddressOf Me.ReadCallback), response)
End Sub
Private Sub ReadCallback(ar As IAsyncResult)
Try
Dim numBytesRead As Integer = Me._stream.EndRead(ar)
If numBytesRead > 0 Then
HandleText(Me._readBuffer)
End If
Catch ex As IOException
Console.WriteLine("-cb- rcv serial 1: " & ex.ToString)
Catch ex As ObjectDisposedException
Console.WriteLine("-cb- rcv serial 2: " & ex.ToString)
End Try
End Sub
Private Class CommsResponse
Implements IAsyncResult
Private ReadOnly _state As Object
Private _isCompleted As [Boolean]
Private ReadOnly _locker As Object = New Object()
Private _evt As ManualResetEvent
Public ReadOnly Property AsyncState As Object Implements IAsyncResult.AsyncState
Get
Return _state
End Get
End Property
Public ReadOnly Property AsyncWaitHandle As WaitHandle Implements IAsyncResult.AsyncWaitHandle
Get
Return GetEvtHandle()
End Get
End Property
Public ReadOnly Property CompletedSynchronously As Boolean Implements IAsyncResult.CompletedSynchronously
Get
Return False
End Get
End Property
Public ReadOnly Property IsCompleted As Boolean Implements IAsyncResult.IsCompleted
Get
Return _isCompleted
End Get
End Property
Private Function GetEvtHandle() As ManualResetEvent
SyncLock _locker
If _evt Is Nothing Then
_evt = New ManualResetEvent(False)
End If
If _isCompleted Then
_evt.[Set]()
End If
End SyncLock
Return _evt
End Function
End Class
End Class