VB.Net - Excel COM对象未发布

时间:2016-04-11 13:40:25

标签: .net vb.net excel com interop

即使在调用ReleaseComObject和GC.Collect方法之后,我也面临着Excel Process仍处于活动状态的问题。

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

后终止

下面的示例代码显示了我正在做的所有事情,以摆脱Excel进程:

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
  

更新:根据我收到的评论,我对代码进行了更改   在other thread之后,它仍然无济于事。我的Excel   流程终止但仅在我关闭用户表单

之后

1 个答案:

答案 0 :(得分:3)

如果您使用的是.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