簡體   English   中英

Excel 2010 com對象引用未發布

[英]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互操作對象?

請注意,在任何給定命令中“永不使用兩個點”的建議(顯然是更受歡迎的答案)是有效的,但實際上幾乎不可能實施。 如果您在代碼中的任何位置出現任何錯誤,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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM