VB.Net - Excel COM 对象未发布

Tej*_*jas 1 .net vb.net com excel interop

我面临的问题是,即使在调用 ReleaseComObject 和 GC.Collect 方法后,Excel Process 仍保持活动状态。

我的 Excel 进程终止,但仅在我关闭用户表单后才终止

下面是示例代码,显示了我为摆脱 Excel Process 所做的所有事情:

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
Run Code Online (Sandbox Code Playgroud)

更新:根据我收到的评论,我按照另一个线程对代码进行了更改,但仍然没有帮助。我的 Excel 进程终止,但仅在我关闭用户表单后才终止

TnT*_*nMn 5

如果您使用 .Net V4 或更高版本,请尝试一下。将所有Button1_Click代码移至子例程中并从Button1_Click. 这将允许该子例程本地的对象超出范围,从而有资格进行垃圾收集。

然后调用清理方法,该方法使用Marshal.AreComObjectsAvailableForCleanup函数来确定释放 COM 对象所需的垃圾收集周期。

评论

如果托管代码和本机代码之间存在大量具有深度依赖关系图的引用,则可能需要很长时间才能清理所有对象。每次 GC 运行时,它都会释放一定数量的 RCW,从而释放底层的 COM 对象。然后,这些 COM 对象将释放其托管引用,并在下次 GC 运行时使更多对象可用于清理,从而重新启动该过程。

AreComObjectsAvailableForCleanup 方法为应用程序提供了一种方法来确定需要发生多少次 GC.Collect 和 GC.WaitForPendingFinalizers 周期才能清理所有内容。

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
Run Code Online (Sandbox Code Playgroud)