472,122 Members | 1,567 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,122 software developers and data experts.

Aborting a worker thread with pending IO: safe handle...disposed e

I read from a serialport using a worker thread. Because the worker thread t
does not loop often, I cannot wait to terminate the worker thread using a
boolean in the While condition.

So I have a StopReader() method that simply aborts the worker thread (is
there a better way for the above situation?).

The StopReader creates an ObjectDisposedException when calling t.Abort(). WHY?

Public Sub StopReader()
'stop the thread running the reader code and wait for the stop to
complete
Try
If Not Me.stoppedReading Then
If t.IsAlive AndAlso t IsNot Thread.CurrentThread Then
t.Abort()
'=THIS Abort() CREATES "OBJECT DISPOSED EXCEPTION - Safe handle has been
disposed"
t.Join()
End If
End If
Catch ex As ThreadStateException
Console.WriteLine("StopReader: ThreadStateException")
Catch ex As Exception
Console.WriteLine("StopReader: " & ex.message)
Finally
Me.stoppedReading = True 'flag that we stopped the reader
worker already
End Try
End Sub

Fine, so I include the lines:
Catch ex As ObjectDisposedException
Console.WriteLine("StopReader: ObjectDisposedException")
however the messages reappears and the catch doesn't work.
Here is the complete code:

Imports System.IO
Imports System.IO.Ports
Imports System.Threading

Public Class SerialPortReader
Implements IDisposable

Private disposedValue As Boolean = False ' To detect redundant
calls
Private stoppedReading As Boolean = False ' false = reader is
working
Dim myPort As SerialPort
Dim t As Thread 'worker thread for reader
Public Sub New()
Try
'create, configure and open a serial port
myPort = New SerialPort("COM4")
With myPort
.BaudRate = 9600
.DataBits = 8
.Parity = Parity.None
.StopBits = StopBits.One
.Handshake = Handshake.None
.DtrEnable = True
.Encoding = System.Text.Encoding.UTF8
End With
myPort.Open()
'delete old data
myPort.DiscardOutBuffer()
myPort.DiscardInBuffer()

'Catch ex As UnauthorizedAccessException
'this happens sometimes and is a confirmed bug (not an issue
here).
Catch ex As Exception
Console.WriteLine("Constructor: Thread abort exception.")
Finally

End Try
End Sub

Public Sub StartReader()
'set up a worker thread to read from the serial port
t = New Thread(AddressOf ReceiveWorker)
t.Start()
End Sub

Public Sub StopReader()
'stop the thread running the reader code and wait for the stop to
complete
Try
If Not Me.stoppedReading Then
If t.IsAlive AndAlso t IsNot Thread.CurrentThread Then
t.Abort() 'THIS CREATES "OBJECT DISPOSED EXCEPTION -
Safe handle has been disposed"
t.Join()
End If
End If
Catch ex As ObjectDisposedException 'doesn't catch the exception
Console.WriteLine("StopReader: ObjectDisposedException")
Catch ex As ThreadStateException
Console.WriteLine("StopReader: ThreadStateException")
Catch ex As Exception
Console.WriteLine("StopReader: " & ex.message)
Finally
Me.stoppedReading = True 'flag that we stopped the reader
worker already
End Try
End Sub

Public Sub ReceiveWorker()
'loop endlessly reading bytes from serial port
Dim myByte As Byte
Try
While (True)
myByte = CType(myPort.ReadByte, Byte) 'read
transparently from serial port
'... process received byte
End While
Catch ex As ThreadAbortException
Console.WriteLine("ReceiveWorker: Thread abort exception.")
Catch ex As Exception
Console.WriteLine("ReceiveWorker: other exception.")
Finally
End Try
End Sub

#Region " IDisposable Support "
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: free managed resources when explicitly called
If Not IsNothing(myPort) Then
If Not Me.stoppedReading Then StopReader()
myPort.Dispose()
End If
End If

' TODO: free shared unmanaged resources
End If
Me.disposedValue = True
End Sub
' This code added by Visual Basic to correctly implement the disposable
pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal
disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region

End Class
Thank you very much. herbert
Jan 22 '07 #1
0 2316

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Steven Brown | last post: by
5 posts views Thread by Stephen Lamb | last post: by
1 post views Thread by Robin Tucker | last post: by
1 post views Thread by Chris Morse | last post: by
7 posts views Thread by Charles Law | last post: by
16 posts views Thread by Paul Schwann | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.