VB.Net-El objeto COM Excel no se libera
interop (1)
Esta pregunta ya tiene una respuesta aquí:
- La aplicación no se cierra después de llamar a dejar de fumar 9 respuestas
Me enfrento a un problema en el que Excel Process permanece activo incluso después de llamar al método ReleaseComObject y GC.Collect.
Mi proceso de Excel finaliza pero SOLO después de cerrar el formulario de usuario
A continuación se muestra un código de muestra que muestra todas las cosas que estoy haciendo para deshacerme del Proceso de 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
ACTUALIZACIÓN : Según los comentarios que recibí, realicé cambios en mi código siguiendo el otro hilo , pero todavía no ayuda. Mi proceso de Excel finaliza pero SOLO después de cerrar el formulario de usuario
Si está utilizando .Net V4 o superior, inténtelo.
Mueva todo su código
Button1_Click
a una subrutina y
Button1_Click
desde
Button1_Click
.
Esto permitirá que los objetos que son locales en esa subrutina se salgan del alcance y, por lo tanto, sean elegibles para la recolección de basura.
Luego llame a un método de limpieza que use la función Marshal.AreComObjectsAvailableForCleanup para determinar cuántos ciclos de recolección de basura se requieren para liberar los objetos COM.
Observaciones
Si hay muchas referencias entre código administrado y nativo con gráficos de dependencia profundos, puede tomar mucho tiempo para que todos los objetos se limpien. Cada vez que se ejecuta un GC, liberará cierto número de RCW, lo que a su vez liberará los objetos COM subyacentes. Esos objetos COM luego liberarán sus referencias administradas y pondrán a disposición más objetos para la limpieza la próxima vez que se ejecute un GC, lo que inicia el proceso nuevamente.
El método AreComObjectsAvailableForCleanup proporciona una forma para que la aplicación determine cuántos ciclos de GC.Collect y GC.WaitForPendingFinalizers deben ocurrir para limpiar todo.
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