Excel 2010 COM对象引用没有发布

下面的代码示例在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互操作对象?

请注意,在任何给定的命令中“从不使用两个点”的build议(显然是更受欢迎的答案)是有效的,但在实践中几乎不可能实施。 如果你在代码中任何地方犯了错误,Excel应用程序将会挂起,并且在这个星球上没有可以帮助你的分析工具 – 你必须仔细检查你所有的代码。 对于一个庞大的代码库,这基本上是不可能的。

在你的代码中,你调用GC.Collect之后没有调用GC.WaitForPendingFinalizers。 这是确保你的垃圾收集调用是同步的。 (GC.Collect在不同的线程上运行,如果您不等待,收集可能会出现与您的后续对象版本不同步的情况,并且您希望释放次要的COM对象,如范围,首先,主要像工作簿和应用程序的COM对象,最后。)在调用GC.Collect和GC.WaitForPendingFinalizers之后,您将要在您的命名引用上调用Marshall.FinalReleaseComObject。

因此,简而言之,策略是调用GC.Collect和GC.WaitForPendingFinalizers以释放不包含引用的COM对象,并调用Marshall.FinalReleaseComObject以释放您持有指定引用的COM对象。

迈克