VB.NET 2019 ListView点击事件关闭窗体报对象已释放异常
异常原因
触发System.ObjectDisposedException的根本原因是你在ListView的Click事件同步执行过程中直接调用Me.Close()。窗体执行Close方法时,会立即释放自身承载的所有控件资源,包括当前触发Click事件的lvSuplidores实例;但此时Click事件的调用栈尚未执行完毕,事件内部还有关联的ListView访问逻辑需要执行,访问已经被释放的ListView控件时就会抛出该异常。
修复方法
- 核心思路是将窗体关闭的操作延迟到当前Click事件完全执行结束后再运行,避免事件逻辑还未走完就释放控件。最简便的实现是通过
BeginInvoke把关闭逻辑投递到UI线程消息队列,等当前事件所有同步代码执行出栈后,再执行关闭操作。 - 额外提示:当前代码采用直接字符串拼接的方式组装SQL语句,存在SQL注入风险,生产环境建议替换为参数化查询实现,该问题和本次抛出的异常无直接关联。
修复后的事件代码如下:
Private Sub lvSuplidores_Click(sender As Object, e As EventArgs) Handles lvSuplidores.Click Dim ca As String ca = lvSuplidores.FocusedItem.Text If cotprov1 Then rs = cn.Execute("C_G_Suplidores_Codigo '" + CStr(cta) + "', '" + CStr(ca) + "'") With rs If Not .EOF Then frCotizaciones.CodPro.Text = rs.Fields("Codpro").Value frCotizaciones.nompro.Text = rs.Fields("Nombpro").Value End If End With frCotizaciones.Comentarios.Focus() ' 延迟执行关闭,等待当前Click事件流程完全结束 Me.BeginInvoke(Sub() Me.Close()) End If End Sub
上述修复的逻辑:
BeginInvoke传入的关闭委托不会在当前代码流中同步执行,会排在当前Click事件所有待执行逻辑之后,等ListView不再需要参与事件流程时才会触发窗体关闭、释放控件,从根源上避免访问已释放对象的问题。
内容的提问来源于stack exchange,提问作者Felipe Sierra
相关产品推荐
相关产品推荐

