【问题标题】:How to properly clean up interop objects in C#如何在 C# 中正确清理互操作对象
【发布时间】:2010-11-25 05:31:37
【问题描述】:

这是一个后续问题 How to properly clean up excel interop objects in c#.

最大的问题是在 Excel 命名空间中使用链接调用(例如 ExcelObject.Foo.Bar() )会阻止对 COM 对象进行垃圾收集。相反,应该显式创建对所使用的每个 COM 对象的引用,并使用 Marhsal.ReleaseComObject() 显式释放它们。

在特定于 Excel COM 对象的链式调用之后不释放 COM 对象的行为是否仅适用于 Excel COM 对象?每当使用 COM 对象时应用这种模式是否有点矫枉过正?

【问题讨论】:

    标签: c# excel interop garbage-collection com-interop


    【解决方案1】:

    COM 对象本质上是非托管代码 - 一旦您开始从托管应用程序调用非托管代码,您就有责任在该非托管代码之后进行清理。

    简而言之,上述帖子中链接的模式对于所有 COM 对象都是必需的。

    【讨论】:

    • ...对于“必要”的一些定义。在进程关闭(或应用程序域卸载,如果首先发生)时,我相信所有尚未被销毁的 RCW(运行时可调用包装器)都会被释放。不幸的是,没有强有力的保证它们会被正确销毁并执行所有终结器。除此之外,如果销毁 COM 对象的时间超过 2 秒,CLR 将终止在该线程上执行的整个终结器队列。
    • @Reuben,请阅读这个问题,关于所提出的问题,答案是 100% 正确的,但是关于 COM 的重要内在细节与这个问题无关。
    【解决方案2】:

    在处理 Office 应用程序时,正确处理版本肯定比许多其他 COM 库更重要,原因有两个。

    1. Office 应用程序作为进程外服务器运行,而不是进程内库。如果您未能正确清理,则会留下一个进程运行。
    2. 即使您调用 Application.Quit,Office 应用程序(尤其是 Excel IIRC)也不会正确终止,如果存在对其 COM 对象的未完成引用。

    对于常规的进程内 COM 库,未能正确清理的后果并没有那么严重。当您的进程退出时,所有进程内库都会随之消失。而且,如果您在不再需要某个对象时忘记调用 ReleaseComObject,最终在对象完成时仍会处理它。

    也就是说,这不是写草率代码的借口。

    【讨论】:

    • 非常好的点 RE:为什么必须清理办公室互操作对象
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多