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

时间:2010-06-22 21:03:55

标签: c# excel interop

我们在代码中的许多地方使用Excel互操作,但是我有一个功能似乎永远不会关闭它使用的Excel进程..我已经简化了代码,它似乎只是每当我在这个函数中打开一个工作簿它会一直闲逛。我已经包含了下面的代码,我确保每个对象都已定义,发布和清空,但Excel仍在运行。

        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);       

5 个答案:

答案 0 :(得分:1)

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

我写了我的经验和解决方案here

答案 1 :(得分:1)

完全猜测,但这一行:

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

返回创建的列?

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

编辑:另外,我不认为你应该在最后将变量设置为null,我认为只是再次访问它们。

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

答案 2 :(得分:1)

已经有一段时间了,因为我已经习惯了这些东西,所以什么都没有跳出来。

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

答案 3 :(得分:1)

我尝试运行您的代码,但我无法重现该问题。如果我使用调试器单步调试,Excel进程会在最后一次调用FinalReleaseComObject后终止。罪魁祸首可能在于您的列表中没有的某些代码吗?

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

excelWorkbook.Foo.Bar();

这会增加Foo对象上的引用计数,让您无法在之后释放它...并且让Excel进程一直闲着,直到您关闭应用程序为止。你可以像这样重写上面的代码:

Foo foo = excelWorkbook.Foo;
foo.Bar();
Marshal.ReleaseComObject(foo);

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

答案 4 :(得分:0)

前几天发生了同样的事情。请参阅我在Excel Automation上关于修复的问题(问题主要涉及多行删除,但我也遇到了与发布它与正确释放所有COM对象有关的问题)。