VB.Net-Excel COM对象未发布
我面临一个问题,Excel进程即使在调用ReleaseComObject和GC.Collect方法后仍保持活动状态 我的Excel进程终止,但仅在我关闭用户表单后终止 下面是示例代码,它显示了我为摆脱Excel流程所做的所有事情:VB.Net-Excel COM对象未发布,.net,vb.net,excel,com,interop,.net,Vb.net,Excel,Com,Interop,我面临一个问题,Excel进程即使在调用ReleaseComObject和GC.Collect方法后仍保持活动状态 我的Excel进程终止,但仅在我关闭用户表单后终止 下面是示例代码,它显示了我为摆脱Excel流程所做的所有事情: Public Class frmTEST Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim objExcel As xl.
Public Class frmTEST
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim objExcel As xl.Application
Dim wbReport As xl.Workbook = Nothing
objExcel = CreateObject("Excel.Application")
Try
wbReport = objExcel.Workbooks.Open("D:\EL\Nicolas\VS Online\Classe A v2\Launcher-v2.2\Resources\Modules\Zoom.xlsm")
Catch ex As Exception
Common.WriteDebugLog("Exception line 44")
End Try
If wbReport Is Nothing Then
MsgBox("Erreur d'ouverture du reporting - Code 745.", vbExclamation)
Exit Sub
End If
With objExcel
.Visible = False
.ScreenUpdating = False
.Calculation = xl.XlCalculation.xlCalculationManual
.DisplayAlerts = False
End With
'' Here I do all my processing which I have removed to make the question more simplified
With objExcel
.Calculation = xl.XlCalculation.xlCalculationAutomatic
.ScreenUpdating = True
.DisplayAlerts = True
End With
''~~> Close & Clean Up
wbReport.Close(SaveChanges:=False)
objExcel.Quit()
Me.ReleaseObject(wbReport)
Me.ReleaseObject(objExcel)
MsgBox("Done")
End Sub
Private Sub ReleaseObject(ByVal obj As Object)
Try
Dim intRel As Integer = 0
Do
intRel = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
Loop While intRel > 0
MsgBox("Final Released obj # " & intRel)
Catch ex As Exception
MsgBox("Error releasing object" & ex.ToString)
obj = Nothing
Finally
GC.Collect()
End Try
End Sub
End Class
更新:根据收到的评论,我对代码进行了更改
遵循规则,但仍然没有帮助。我的Excel
进程终止,但仅在我关闭用户窗体之后
如果您使用的是.NETV4或更高版本,请尝试一下。 将所有
按钮1\u单击
代码移动到子例程中,并从按钮1\u单击
调用它。这将允许该子例程的本地对象超出范围,从而有资格进行垃圾收集
然后调用一个cleanup方法,该方法使用函数确定释放COM对象需要多少垃圾收集周期
评论
如果托管代码和本机代码之间有大量引用,并且带有深度依赖关系图,那么清理所有对象可能需要很长时间。每次GC运行时,它都会释放一些RCW,从而释放底层COM对象。然后,这些COM对象将释放其托管引用,并在下次GC运行时使更多对象可用于清理,从而重新启动该过程
AreComObjectsAvailableForCleanup方法为应用程序提供了一种方法,用于确定需要执行多少个GC.Collect和GC.WaitForPendingFinalizer循环才能清除所有内容
从ReleaseObject()方法中删除Try/Catch,它在代码中隐藏了一个bug。永远不要写像这样的代码,谢谢,但是没有帮助。请检查我更新的问题。我投票重新打开此问题,因为它不是所选问题的副本。这个问题是在COM发布的mumbo jumbo/dot规则建议之后提出的,但仍然失败,因为这个解决方案不是答案。谢谢。这很有效!将COM访问移到单独的作用域中的一个原因是,调试器将保留方法内的对象,并防止它们被垃圾收集,即使任何代码都无法再访问它们。即使在执行显式GC.Collect()时,它也可以使COM对象比您预期的时间更长。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ExcelWork()
Cleanup()
End Sub
Private Sub ExcelWork()
Dim objExcel As xl.Application
Dim wbReport As xl.Workbook = Nothing
objExcel = CreateObject("Excel.Application")
Try
wbReport = objExcel.Workbooks.Open("D:\EL\Nicolas\VS Online\Classe A v2\Launcher-v2.2\Resources\Modules\Zoom.xlsm")
Catch ex As Exception
Common.WriteDebugLog("Exception line 44")
End Try
If wbReport Is Nothing Then
MsgBox("Erreur d'ouverture du reporting - Code 745.", vbExclamation)
Exit Sub
End If
With objExcel
.Visible = False
.ScreenUpdating = False
.Calculation = xl.XlCalculation.xlCalculationManual
.DisplayAlerts = False
End With
'' Here I do all my processing which I have removed to make the question more simplified
With objExcel
.Calculation = xl.XlCalculation.xlCalculationAutomatic
.ScreenUpdating = True
.DisplayAlerts = True
End With
''~~> Close & Clean Up
wbReport.Close(SaveChanges:=False)
objExcel.Quit()
MsgBox("Done")
End Sub
Private Sub Cleanup()
Do
GC.Collect()
GC.WaitForPendingFinalizers()
Loop While Marshal.AreComObjectsAvailableForCleanup
End Sub