I have method in my form that is running a do while loop in a new thread.
That for loop exits once a sentinel value is set to true (set by another method that handles Me.FormClosing
)
The issue is that when the form closes, I get occasionally get two exceptions.
ObjectDisposedException
and ComponentModel.Win32Exception
.
How do I properly exit a form without "eating" these exceptions and ignoring them.
Code:
Dim _exit As Boolean
Public Sub test()
Dim task As Thread = New Thread(
Sub()
Do
checkInvoke(Sub() a.append("a"))
Loop While _exit = False
End Sub)
End Sub
Private Sub checkInvoke(ByVal _call As Action)
If Me.InvokeRequired Then
Me.Invoke(Sub() checkInvoke(_call))
Else
_call.Invoke()
End If
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
_exit = True
End Sub
Where does the error come from ?
This can be a bit confusing but it actually is pretty logical...
FormClosing
is then called which sets _exit
to True
_exit
value then ends the loop, everything goes fine.ObjectDisposedException
How to prevent this ?
One thing you can do is, in your FormClosing
event, wait for the Thread to end, then letting the system close the form :
Private _isFinished As Boolean = False
Private _exit As Boolean = False
Public Sub test()
Dim task As Thread = New Thread(
Sub()
Do
checkInvoke(Sub() a.append("a"))
Loop While _exit = False
'We inform the UI thread we are done
_isFinished = True
End Sub)
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
_exit = True
While Not _isFinished
Application.DoEvent() 'We can't block the UI thread as it will be invoked by our second thread...
End While
End Sub