我的表单中有一个方法,它在新线程中运行 do while 循环。
一旦哨兵值设置为 true(由处理 Me.FormClosing
的另一个方法设置),for 循环就会退出
问题是,当表单关闭时,我偶尔会遇到两个异常。
ObjectDisposeException
和 ComponentModel.Win32Exception
。
如何正确退出表单而不“吃掉”这些异常并忽略它们。
代码:
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
最佳答案
错误从何而来?
这可能有点令人困惑,但实际上非常合乎逻辑......
- 用户(或其他人)关闭表单。 然后调用
FormClosing
,将_exit
设置为True
- 然后表单自行关闭,并销毁其句柄。
- 现在,这取决于它有时会在哪里抛出异常:
- 无论是线程刚刚完成调用还是循环,检查
_exit
值然后结束循环,一切顺利。 - 要么是它刚刚开始Invoke,然后调用一个调用UI线程的方法来修改刚刚处理过的表单上的某些内容,不再处理这个表单,导致
ObjectDisposeException
<
- 无论是线程刚刚完成调用还是循环,检查
如何防止这种情况发生?
您可以做的一件事是,在 FormClosing
事件中,等待线程结束,然后让系统关闭表单:
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
关于vb.net - 正确关闭在新线程中运行循环的表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37796979/