繁体   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