C# .net Excel Interop leaves Excel process hanging
我们在代码中的很多地方都使用excel interop,但是我有一个函数似乎从来没有关闭过它使用的excel进程。我已经简化了代码,每当我在这个函数中打开一个工作簿时,它就好像一直在挂着一样。我已经包含了下面的代码,我已经确保每个对象都被定义、释放并为空,而Excel仍然在运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | System.Data.DataTable dtExcelSheet = new System.Data.DataTable(); Microsoft.Office.Interop.Excel.Application excelObject = new Microsoft.Office.Interop.Excel.Application(); dtExcelSheet.Columns.Add("SheetName", typeof(string)); dtExcelSheet.Columns["SheetName"].ReadOnly = false; dtExcelSheet.Columns["SheetName"].Caption ="Sheet Name"; Workbooks wbs = excelObject.Workbooks; Workbook excelWorkbook = wbs.Add(excelFile); excelWorkbook.Close(false, System.Reflection.Missing.Value, System.Reflection.Missing.Value); wbs.Close(); excelObject.Quit(); int i1 = Marshal.FinalReleaseComObject(excelWorkbook); int i2 = Marshal.FinalReleaseComObject(wbs); int i3 = Marshal.FinalReleaseComObject(excelObject); excelWorkbook = null; wbs = null; excelObject = null; GC.GetTotalMemory(false); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.GetTotalMemory(true); |
我试图运行您的代码,但无法复制该问题。如果我使用调试器单步执行,Excel进程将在最后一次调用
在使用COM互操作时,我发现以非常微妙的方式增加COM对象的引用计数太容易了。例如,假设您执行如下操作:
1 | excelWorkbook.Foo.Bar(); |
这可以增加
它没有那么漂亮,但是在使用完之后,它会减少
我已经有一段时间没有和这些东西混在一起了,所以没什么能跳出来。
在这些情况下,我通常的建议是将Excel应用程序对象设置为
完全猜对了,但这一行:
1 |
是否返回创建的列?
如果是这样的话,您可能需要存储该引用并在最后清除它。
编辑:另外,我认为您不应该在末尾将变量设置为空,我认为这只是再次访问它们。
您不必告诉GC收集等等,但我认为这可能是您的测试代码。
确保您没有在后台线程上调用Excel。我有一个类似的问题,我在清理所有的COM对象,但Excel仍然没有死,这就是问题所在。
我在这里写下了我的经历和解决方案。
前几天我也发生了同样的事。请参阅我关于Excel自动化的问题中关于修复的部分(问题主要涉及多行删除,但我也遇到了与您原来相同的问题,即它与正确释放所有COM对象有关)。