Dot-Net

使用 IDisposable 清理 Excel 互操作對象

  • August 5, 2014

在我公司,發布 Excel 互操作對象的常用方法是使用IDisposable以下方式:

Public Sub Dispose() Implements IDisposable.Dispose
   If Not bolDisposed Then
       Finalize()
       System.GC.SuppressFinalize(Me)
   End If
End Sub

Protected Overrides Sub Finalize()
   _xlApp = Nothing
   bolDisposed = True
   MyBase.Finalize()
End Sub

where_xlApp在建構子中通過以下方式創建:

Try
   _xlApp = CType(GetObject(, "Excel.Application"), Excel.Application)
Catch e As Exception
   _xlApp = CType(CreateObject("Excel.Application"), Excel.Application) 
End Try

客戶端使用using-statement執行有關 excel 互操作對象的程式碼。

我們完全避免使用兩點規則。現在我開始研究如何發布 (Excel) Interop Objects 以及我發現的幾乎所有關於它的討論,例如如何正確清理 excel interop objectsRelease Excel Objects are using most Marshal.ReleaseComObject(),但沒有一個使用IDisposable介面。

我的問題是:使用IDisposable互動來發布 excel 互操作對像有什麼缺點嗎?如果是這樣,這些缺點是什麼。

使用 IDisposable Interace 有什麼缺點嗎

當然,它什麼也沒做。使用Using或呼叫 Dispose() 從來都不是將變數設置為 Nothing 的合適方法。這就是您的程式碼所做的一切。

我們完全避免使用兩點規則。

隨意繼續忽略它,這是胡說八道,只會引起悲傷。部落格作者的隱含斷言是,這樣做會迫使程序員使用變數來儲存 xlApp.Workbooks 的值。所以他以後會有一個戰鬥的機會,不要忘記呼叫releaseObject()。但是還有更多語句可以生成不使用點的介面引用。像 Range(x,y) 這樣的東西,那裡有一個隱藏的 Range 對象引用,你永遠看不到。必須同時儲存它們只會產生令人難以置信的複雜程式碼。

僅僅忽略一個就足以完全無法完成工作。完全無法調試。這是 C 程序員必須編寫的那種程式碼。並且經常慘遭失敗,大型 C 程序經常洩漏記憶體,並且他們的程序員花費大量時間來查找這些洩漏。當然不是 .NET 方式,它有一個垃圾收集器來自動執行此操作。它永遠不會出錯。

麻煩的是,處理工作有點慢。非常設計。沒有人注意到這一點,除了這種程式碼。您可以看到垃圾收集器沒有執行,您仍然看到 Office 程序正在執行。當您編寫 xlapp.Quit() 時它並沒有退出,它仍然存在於任務管理器的程序選項卡中。他們想要發生的事情是當他們這麼說時它就退出了。

這在 .NET 中很有可能,您當然可以強制 GC 完成工作:

GC.Collect()
GC.WaitForPendingFinalizers()

繁榮,每個Excel 對象引用都會自動釋放。無需自己儲存這些對象引用並顯式呼叫 Marshal.ReleaseComObject(),CLR 會為您完成。它永遠不會出錯,它不使用或不需要“兩點規則”,並且可以輕鬆找到那些隱藏的介面引用。


然而,重要的是你把這段程式碼放在哪裡**。**大多數程序員把它放在錯誤的地方,使用那些 Excel 介面的方法。這很好,但在調試程式碼時不起作用,這是一個在這個答案中解釋的怪癖。在部落格作者的程式碼中,正確的做法是將程式碼移動到一個小輔助方法中,我們稱之為 DoExcelThing()。像這樣:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
   DoExcelThing()
   GC.Collect()
   GC.WaitForPendingFinalizers()
   '' Excel.exe no longer running anymore at this point
End Sub

請記住,這實際上只是一個調試工件。程序員只是討厭不得不使用任務管理器來殺死殭屍 Excel.exe 實例。當他們停止調試器時殭屍化,阻止程序正常退出並收集垃圾。這是正常的。當您的程序因任何原因在生產中當機時,也會發生這種情況。把你的精力放在它所屬的地方,從你的程式碼中消除錯誤,這樣你的程序就不會死掉。GC 不需要更多的幫助。

引用自:https://stackoverflow.com/questions/25134024