[英]Excel 2010 com object references not released
以下代碼示例在Excel 2007中運行良好,但是當我安裝Excel 2010(32位)時,除非我添加了GC.Collect(),否則將保持excel.exe進程處於打開狀態。 我的簡單問題是我做錯了什么? 在我看來,我正在釋放我使用的所有東西。
public override void Update()
{
StatusBox.AddStatus("Opening File " + ImportPath);
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook wb = app.Workbooks.Open(ImportPath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Microsoft.Office.Interop.Excel.Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Sheets[1];
Range rng = ws.Cells.SpecialCells(XlCellType.xlCellTypeLastCell, Type.Missing);
int LastRow = rng.Row;
StatusBox.AddStatus(LastRow.ToString() + " Rows Found in File");
StatusBox.AddStatus("Closing File " + ImportPath);
System.Runtime.InteropServices.Marshal.ReleaseComObject(rng);
rng = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(ws);
ws = null;
wb.Close(true, ImportPath, null);
System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
wb = null;
GC.Collect();
app.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
app = null;
}
您需要同時調用GC.Collect / GC.WaitForPendingFinalizers 和 Marshall.FinalReleaseComObject。
有關詳細信息,請參閱我的答案
請注意,在任何給定命令中“永不使用兩個點”的建議(顯然是更受歡迎的答案)是有效的,但實際上幾乎不可能實施。 如果您在代碼中的任何位置出現任何錯誤,Excel應用程序將掛起,並且地球上沒有可以幫助您的分析工具 - 您必須通過眼睛檢查所有代碼。 對於大型代碼庫,這基本上是不可能的。
在您的代碼中,在調用GC.Collect之后,您沒有調用GC.WaitForPendingFinalizers。 這是確保垃圾回收調用是同步的必要條件。 (GC.Collect在不同的線程上運行,如果你不等它,那么集合可能就你的subseqent對象版本而無序發生,並且你想要釋放次要的COM對象,比如Ranges,首先和主要的最后一個COM對象,如Workbooks和Application。)在調用GC.Collect和GC.WaitForPendingFinalizers后,您需要在命名引用上調用Marshall.FinalReleaseComObject。
因此,簡而言之,策略是調用GC.Collect和GC.WaitForPendingFinalizers來釋放您沒有引用的COM對象,並調用Marshall.FinalReleaseComObject來釋放您持有命名引用的COM對象。
- 邁克
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.