【问题标题】:Release COM Components发布 COM 组件
【发布时间】:2010-09-15 01:58:34
【问题描述】:

真的有必要通过调用 Marshal.ReleaseComObject(..) 从 Office PIA 释放 COM 组件吗?

我在网上找到了关于这个主题的各种相互矛盾的建议。在我看来,由于 Outlook PIA 总是返回对其接口的新引用作为其方法的返回值,因此没有必要显式释放它。我说的对吗?

【问题讨论】:

    标签: c# .net outlook add-in pia


    【解决方案1】:

    有一些好的做法here 使用托管包装器..值得一试..

    【讨论】:

    • 谢谢,这是一篇好文章。但是,我需要知道我是否需要从现有的 Office PIA 中显式释放 COM 组件,而不是制作自己的包装器。
    【解决方案2】:

    也许这只是我的迷信,但我决定通过 Marshal.ReleaseComObject() 明确发布 Office PIA,因为当我的应用程序崩溃时,对 Excel 和 Word 的引用保持打开状态。我没有深入挖掘原因(愚蠢的截止日期),但将它们作为我班级的处置模式的一部分发布解决了这个问题。

    【讨论】:

      【解决方案3】:

      PIA 是 .NET 互操作包装器。这意味着在对象的析构函数(或 Dispose - 我不记得了)会自动处理它的引用计数。诀窍是在执行垃圾收集器之前不会释放一些引用。这取决于 COM 对象实例化的内容。例如,打开数据库游标的 COM 对象将使这些游标在内存中保持活动状态,直到这些游标上的引用计数被释放。使用 .NET/COM 互操作,在垃圾收集器执行或使用 Marshal.ReleaseComObject(或 FinalReleaseComObject)显式释放引用之前,不会释放引用。

      我个人没有使用过 Microsoft Office PIA,但在大多数情况下,您不应该必须明确发布引用。只有当您的应用程序开始锁定其他资源或崩溃时,您才应该开始怀疑悬空引用。

      编辑:如果您遇到确实需要清理 COM/Interop 对象的情况,请使用 Marshal.FinalReleaseComObject - 它将引用计数一直为零,而不是仅递减 1 - 并将对象引用设置为 null。如果您真的想要安全,则可以显式强制垃圾回收 (GC.Collect),但要小心不要过于频繁地执行 GC,因为它会导致明显的性能损失。

      【讨论】:

        【解决方案4】:

        如果您希望 Office 应用程序的实例退出,您确实需要这样做,如this post 中所述。

        除了最简单的情况外,很难在所有情况下都做到正确。

        【讨论】:

        • 但是,如果我省略了清理代码,则不会发生任何不好的事情。在这种情况下,Outlook 甚至会更快关闭,我在网上找到了几篇文章,指出不需要释放 Outlook COM 对象。
        【解决方案5】:

        对于 Microsoft Office,一般来说,您确实需要明确发布您的参考资料,这可以分两个阶段安全地完成:

        (1) 首先通过调用 GC.Collect() 然后调用 GC.WaitForPendingFinalizers() 释放所有您不持有命名对象变量的次要对象。 (如果涉及的对象可能具有终结器,例如在使用 Visual Studio Tools for Office (VSTO) 时,您需要调用它两次。)

        (2) 然后通过在每个对象上调用 Marshall.FinalReleaseComObject() 显式释放您持有命名变量的对象。

        就是这样。 :-)

        我更详细地讨论了这个 in a previous post,以及一个代码示例。

        【讨论】:

        【解决方案6】:

        我的经验表明您必须这样做,否则(至少是 Outlook)应用程序可能根本不会关闭。

        但这又会引发另一波蠕虫,因为看起来 RCW 是每个进程的,因此您可以破坏其他一些插件,这些插件恰好具有对同一对象的引用。

        我已经发布了一个相关的问题here,但我仍然没有明确的答案。一旦我知道更多,我会编辑这篇文章。

        【讨论】:

          【解决方案7】:

          关于 .Net/COM 互操作有一个简单的规则 - 如有疑问,请始终使用 Release()。 :-)

          【讨论】:

            【解决方案8】:

            对于 VS 2010,请参阅 Marshal.ReleaseComObject Is Considered Dangerous

            【讨论】:

              猜你喜欢
              • 2012-12-21
              • 2011-03-25
              • 1970-01-01
              • 2018-08-14
              • 2011-02-11
              • 1970-01-01
              • 1970-01-01
              • 2012-08-14
              • 2011-01-04
              相关资源
              最近更新 更多