2016-04-11 58 views
1

Excel Process'in ReleaseComObject ve GC.Collect yöntemini çağırdıktan sonra bile etkin kaldığı bir sorunla karşı karşıyayım.VB.Net - Excel COM Nesne çıkmıyor

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 

:

My Excel Süreci ama Kullanıcı Formunu Aşağıda

kapatmak SADECE sonra sonlandırır yapıyorum her şeyi Excel Süreci kurtulmak ne gösteren örnek kod UPDATE: Alınan yorumlara dayanarak, other thread'u izleyerek kodumda değişiklikler yaptım, ancak yine de yardımcı olmuyor. Benim Excel İşlemi Net V4 veya daha kullanıyorsanız ben Kullanıcı Formu

+1

Sil deneyin/Yakalama, sizin kodunda bir hata saklıyor. Asla hepsini bir kez daha yakalamayı deneyin. –

+0

Teşekkürler ama yardım etmedi. Lütfen güncellenmiş sorumu kontrol edin. – Tejas

+0

Bu soruyu yeniden açmak için oy verdim, çünkü seçili olanın kopyası değil. Bu soru COM serbest bırakılması mumbo jumbo/dot kuralını tavsiye etti ve hala başarısız çünkü _solution_ cevap değil. – TnTinMn

cevap

3

kapatmak SADECE sonra ancak sonlandırır, bu deneyin. Tüm Button1_Click kodunuzu bir alt programa taşıyın ve Button1_Click numaralı telefondan arayın. Bu, bu alt rutine yerel olan nesnelerin kapsam dışı kalmasına ve böylece çöp toplama için uygun olmasına izin verecektir. Ardından, COM nesnelerini boşaltmak için kaç tane çöp toplama döngüsü gerektiğini belirlemek üzere Marshal.AreComObjectsAvailableForCleanup işlevini kullanan bir temizleme yöntemini çağırın. tüm nesneler temizlemek için uzun bir zaman alabilir derin bağımlılık grafikler ile yönetilen ve yerel kod arasındaki referansların çok varsa

Açıklamalar. GC her çalıştığında, bazı COM'ları serbest bırakır, bu da temel olarak COM nesnelerini serbest bırakır. Bu COM nesneleri daha sonra yönetilen referanslarını yayınlayacak ve bir dahaki sefer GC işlemini çalıştığında daha fazla nesneyi temizleme için kullanılabilir hale getirecektir.

AreComObjectsAvailableForCleanup yöntemi, uygulamanın her şeyi temizlemek için GC.Collect ve GC.WaitForPendingFinalizer'ın kaç döngüsünün gerçekleşmesi gerektiğini belirlemesi için bir yol sağlar. senin ReleaseObject() yöntemi dan

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 
+0

Teşekkürler. Bu çok iyi çalıştı! – Tejas

+0

COM erişiminin ayrı bir kapsamda taşınmasının nedenlerinden biri, hata ayıklayıcının, yöntem içinde bulunan nesneler üzerinde duracak ve herhangi bir kod tarafından erişilemese bile, toplanan çöplerin alınmasını engelleyecektir. COM nesneleri açık bir GC.Collect() yaparken bile beklediğinizden daha uzun süre canlı tutabilir. – Govert