挂起互操作COM对象的问题

时间:2010-12-21 19:51:54

标签: c# excel com interop

我有一个使用COM互操作的应用程序来创建一个在客户机上的Excel中打开的电子表格。但是,如果我查看任务管理器,当用户关闭Excel时,似乎并不总是结束EXCEL.exe进程。

如果我正在保存工作簿并以编程方式关闭Excel,我只会使用Marshal.ReleaseComObject()来清理,但由于我依赖于手动关闭程序,我不知道该怎么做。有什么建议吗?

4 个答案:

答案 0 :(得分:9)

在发布所有进程外对象之前,Excel无法终止。所以它只是隐藏了它的用户界面并继续运行。直到您的程序退出或者您的所有Excel对象引用为空并且终结器线程运行。退出程序将是一个明显的解决方案。或者您可以强制终结器线程运行:

GC.Collect();
GC.WaitForPendingFinalizers();

ReleaseComObject()很少有效,因为它很容易忘记中间COM对象引用。像WorkBooks [index]一样,这是一个你看不到的枚举器。让GC做出自己的决定将是更明智的选择,如果你继续运行并做好工作那么就会发生。

答案 1 :(得分:3)

可能Excel.exe仍处于打开状态,因为用户在Excell应用程序的同一实例中打开了另一个文档。在这种情况下,您可能不应该终止Excel.exe进程。

如果您确保关闭所有打开的文档并释放所有创建的对象,那么为什么确保Excel.exe终止是很重要的?也许这个过程正在为另一个应用程序或用户服务?

答案 2 :(得分:2)

可能有很多原因(包括Ran的),但我看到很多MapPoint(另一个带有COM接口的Microsoft应用程序)是你必须确保清除所有对象引用,以便垃圾收集器可以清理它们。悬挂的一个低位对象足以阻止应用程序关闭并退出进程列表。

答案 3 :(得分:2)

如果我打开Excel应用程序和工作簿:

Excel.Application app = new Excel.Application();
Excel.Workbook wb = app.Workbooks.Open(...);

然后我在finally语句(或其他适当的结束事件)中使用wb.Close()app.Quit()方法。这将清除Exel.exe进程。无需调用Marshall.ReleaseComObject或GC方法。