【问题标题】:C# .net Excel Interop leaves Excel process hangingC# .net Excel Interop 使 Excel 进程挂起
【发布时间】:2010-08-26 12:21:24
【问题描述】:

我们在代码中的许多地方都使用 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);       

【问题讨论】:

    标签: c# excel interop


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      完全猜测,但是这一行:

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

      返回创建的列?

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

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

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

      【讨论】:

      • 匿名专栏也是我的猜测。
      • @Rick:你说得对,我看错了。我的答案剩下的唯一一件事就是不要在最后将它们设置为 null,即使这听起来毫无意义也可能值得尝试。
      【解决方案3】:

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

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

      【讨论】:

      • 如果发生这种情况,您只需设置 DisplayAlerts = false
      【解决方案4】:

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

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

      excelWorkbook.Foo.Bar();
      

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

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

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 2013-08-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-10
          • 1970-01-01
          • 1970-01-01
          • 2017-07-12
          • 2023-04-06
          相关资源
          最近更新 更多