VB.NET关闭窗体时出现System.ObjectDisposedException异常求助
嘿,我太懂这种“明明逻辑看上去没问题,但就是卡壳”的糟心感了!咱们一步步拆解你遇到的这个问题——用VS2015开发,两个窗体,设置了「最后一个窗体关闭时退出」,但点击frmDashboard的退出按钮执行Me.Close()后,程序却没正常退出对吧?
下面是几个我碰到过的常见原因和对应的排查/解决办法:
1. 有没有隐藏的窗体在后台挂着?
有时候咱们以为只有两个窗体在运行,但可能某个窗体是用Show()打开后,不小心用Hide()代替了Close(),或者打开后没正确关闭,导致它在后台偷偷“存活”,程序自然不会退出。
排查方法:在你的recExit_Click方法里加一段调试代码,看看当前所有打开的窗体:
Private Sub recExit_Click(sender As Object, e As EventArgs) Handles recExit.Click ' 先打印当前所有打开的窗体 For Each frm As Form In Application.OpenForms Debug.WriteLine($"打开的窗体:{frm.Name}") Next Me.Close() End Sub
然后运行程序,点击退出按钮,去VS的「输出」窗口里看,是不是还有其他你没意识到的窗体没关闭。
2. 窗体关闭事件被意外拦截了?
检查一下frmDashboard或者另一个窗体的FormClosing事件代码,有没有写过类似e.Cancel = True的逻辑?比如有些时候为了提示用户保存数据,会临时阻止窗体关闭,但如果逻辑判断出错,就会导致窗体永远关不掉。
举个反例,要是你写了这样的代码,就会出问题:
Private Sub frmDashboard_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing ' 如果这里的判断逻辑出错,就会一直阻止关闭 e.Cancel = True End Sub
3. 程序的关闭模式设置错了?
你说设置了「最后一个窗体关闭时退出」,但再确认一下这个配置:右键项目 → 属性 → 应用程序 → 关闭模式,是不是真的选了「当最后一个窗体关闭时」。
要是不小心选成了「当启动窗体关闭时」,而你的启动窗体不是frmDashboard(比如是另一个Form1),那就算关闭了frmDashboard,只要启动窗体还在(哪怕是隐藏状态),程序就会继续运行。
4. 后台线程还在“硬撑”着程序?
如果你的程序里用到了后台线程(比如Thread或者BackgroundWorker),而且线程的IsBackground属性设为False,那就算所有窗体都关闭了,这个线程还会让程序进程留在任务管理器里。
解决办法:把这类后台线程的IsBackground设为True,这样当主线程退出时,后台线程会自动终止:
Dim workerThread As New Thread(AddressOf YourBackgroundMethod) workerThread.IsBackground = True ' 关键设置 workerThread.Start()
快速调试步骤总结
- 在
recExit_Click方法里加断点,确认点击按钮时确实执行到了Me.Close(); - 给
frmDashboard加个FormClosed事件,弹窗验证窗体是否真的关闭:
Private Sub frmDashboard_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed MessageBox.Show("frmDashboard 已关闭") End Sub
- 如果窗体确实关闭了但程序还在运行,用第一步的
Application.OpenForms排查剩余窗体,或者检查后台线程。
要是你发现是启动窗体还在隐藏运行,可以在退出时同时关闭它:
Private Sub recExit_Click(sender As Object, e As EventArgs) Handles recExit.Click Me.Close() ' 关闭启动窗体 If My.Application.MainForm IsNot Nothing Then My.Application.MainForm.Close() End If End Sub
内容的提问来源于stack exchange,提问作者Andrew Bartholomew

