C#.net Excel Interop使Excel进程挂起

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进程将在最后一次调用FinalReleaseComObject后终止。是否有可能是因为某些代码不在您的列表中?

在使用COM互操作时,我发现以非常微妙的方式增加COM对象的引用计数太容易了。例如,假设您执行如下操作:

1
excelWorkbook.Foo.Bar();

这可以增加Foo对象上的引用计数,使您以后无法释放它……并使Excel进程在关闭应用程序之前一直逗留。您可以这样重新编写上述代码行:

2

它没有那么漂亮,但是在使用完之后,它会减少Foo对象的引用计数。


我已经有一段时间没有和这些东西混在一起了,所以没什么能跳出来。

在这些情况下,我通常的建议是将Excel应用程序对象设置为Visible = true,以查看是否没有弹出对话框。Excel/Word有时会拒绝关闭,如果他们认为有一个模式对话框打开,不管你做什么。不管怎样,这是第一件要检查的事情。


完全猜对了,但这一行:

1
dtExcelSheet.Columns.Add("SheetName", typeof(string));

是否返回创建的列?

如果是这样的话,您可能需要存储该引用并在最后清除它。

编辑:另外,我认为您不应该在末尾将变量设置为空,我认为这只是再次访问它们。

您不必告诉GC收集等等,但我认为这可能是您的测试代码。


确保您没有在后台线程上调用Excel。我有一个类似的问题,我在清理所有的COM对象,但Excel仍然没有死,这就是问题所在。

我在这里写下了我的经历和解决方案。


前几天我也发生了同样的事。请参阅我关于Excel自动化的问题中关于修复的部分(问题主要涉及多行删除,但我也遇到了与您原来相同的问题,即它与正确释放所有COM对象有关)。