【问题标题】:Excel processes not ending C#Excel 进程未结束 C#
【发布时间】:2020-11-18 16:17:53
【问题描述】:

我正在运行我的 C# 应用程序,它使用循环打开许多 excel 文件,但是在每个循环结束时,我调用以下函数来结束 excel 进程,但任务管理器中的进程仍然没有结束,我不知道为什么.谁能给点建议?

private void xlCleanup(Excel.Application xlApp, Excel.Workbook xlWorkbook, Excel.Worksheet xlWorksheet, Excel.Range xlRange)
    {
        //cleanup
        GC.Collect();
        GC.WaitForPendingFinalizers();

        //rule of thumb for releasing com objects:
        //  never use two dots, all COM objects must be referenced and released individually
        //  ex: [somthing].[something].[something] is bad

        //release com objects to fully kill excel process from running in the background
        if (xlRange != null || xlWorksheet != null)
        {
            Marshal.ReleaseComObject(xlRange);
            Marshal.ReleaseComObject(xlWorksheet);
        }
        //close and release
        
        xlWorkbook.Close(0);
        Marshal.ReleaseComObject(xlWorkbook);

        //quit and release
        xlApp.Quit();
        Marshal.ReleaseComObject(xlApp);

    }

【问题讨论】:

  • 您必须手动释放 COM 对象的真正原因是您使用它们的线程不兼容 COM。如果它具有 COM 兼容,并且具有 COM 兼容消息泵,则办公室 COM 实例将自行清理,并且不需要 ReleaseComObject。
  • 这里有一些关于为什么你不应该使用 ReleaseCOMObject 的更多信息 - devblogs.microsoft.com/visualstudio/… 和一个讨论消息泵要求的信息 - docs.microsoft.com/en-us/archive/blogs/cbrumme/…
  • 我还应该指出,现在文章都是旧的,但那是因为 COM 也是。

标签: c# excel process


【解决方案1】:

尝试将此添加到方法的末尾。它为我解决了这个问题:

xlRange = null;
xlWorksheet = null;
xlWorkbook = null;
xlApp = null;
GC.Collect();

(已编辑以将 xl vars 设置为 null)

(编辑#2)

还在这里阅读答案: How do I properly clean up Excel interop objects?

【讨论】:

  • 您不需要将 C# 对象设置为 null 以便它们被 GC 收集。
  • 我明白,但无论出于何种原因,这是我必须做的,以确保应用程序完全发布 Excel。我不声称知道为什么,我只是声称它有效(对我来说)。不将它们设置为 null 有时会使 Excel 在任务管理器中保持“活动”状态。
  • 查看我对这个问题的评论。还要记住,调试版本的行为与发布版本不同,因为调试器将保持本地人的活动状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多