vb.net - 正确关闭在新线程中运行循环的表单

标签 vb.net multithreading winforms formclosing

我的表单中有一个方法,它在新线程中运行 do while 循环。

一旦哨兵值设置为 true(由处理 Me.FormClosing 的另一个方法设置),for 循环就会退出

问题是,当表单关闭时,我偶尔会遇到两个异常。

ObjectDisposeExceptionComponentModel.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

最佳答案

错误从何而来?

这可能有点令人困惑,但实际上非常合乎逻辑......

  1. 用户(或其他人)关闭表单。
  2. 然后调用
  3. FormClosing,将_exit设置为True
  4. 然后表单自行关闭,并销毁其句柄。
  5. 现在,这取决于它有时会在哪里抛出异常:
    • 无论是线程刚刚完成调用还是循环,检查_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/

相关文章:

.net - 清除 Windows 窗体中的 DrawRectangle

.net - MSBuild 编译错误怪异

C# UML 类图

c# - 继承窗体上的 OnLoad 事件不会被调用

c# - 使用矩阵单独旋转矩形

.net - 将字符串替换为目标格式

.net - 如何使用 VB.NET 获取 Excel 文件的确切行数?

java - 是否有用于调度依赖可运行对象的 Java 库(在依赖 DAG 中给出)?

ios - 应用程序拒绝 SIGABRT iOS

c - C语言支持多线程吗?