【问题标题】:Finalizing a COM object完成 COM 对象
【发布时间】:2010-05-31 15:49:34
【问题描述】:

我正在尝试实现一个单例类,其中包含一个 com 对象。类实现了 IDisposable 接口,但是当我尝试实现终结方法时,我得到了从另一个线程访问 com 对象的异常。

这是因为 clr 在终结对象时使用了不同的线程。

有没有办法实现这样的事情,或者我只是做错了什么?

【问题讨论】:

    标签: c# com interop


    【解决方案1】:

    如果类直接管理非托管资源,您只需要实现终结器。 COM 对象被包装在 RCW(运行时可调用包装器)中,因此在您的类型和 COM 接口指针之间已经存在托管类型。

    【讨论】:

    • 你说如果你的类直接管理非托管资源,你只需要实现一个终结器。如果您的类包含任何实现 IDisposable 的对象,您还应该实现终结器。
    • hm 让我们来看一下我正在使用 Office.Interop 完成后访问 Word 的拼写检查功能的示例,我需要关闭 Word 后台应用程序,所以我实现了包含 WordApplication 实例和希望它在处理或完成时调用关闭方法,问题不在于资源,而在于调用 word 应用程序实例的关闭方法
    • @dewald:不正确。在这种情况下,实现 IDisposable 以允许调用者在不等待 GC 的情况下进行清理。但是您不需要终结器:GC 将为您终结引用的本机资源包装器(这是在终结器中您不能使用引用的托管对象的规则的推论,因为 GC 可能已经已经摧毁了他们)。
    • @Neverrav:当 GC 从 Office PIA 完成 RCW 并释放对 Application 对象的最后一个引用时,Office 应用程序应该关闭。或者您在 Dispose 实现中使用 Marshall 帮助程序显式释放。实际上,Office 应用程序并不总是在它们应该消失的时候消失(我在纯 COM 案例中遇到过这个问题,这是 Office 自动化的问题)。
    • 我承认,你是对的。我记错了处置模式。我错误地认为,每次你实现 IDisposable 时,你也应该覆盖 Finalize 方法。我重新阅读了 MSDN 上的“实现 Dispose 方法”,它说只有在直接管理非托管资源而不是通过托管引用间接管理时才应该覆盖 Finalize。
    猜你喜欢
    • 2015-11-13
    • 2021-08-11
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 2018-09-10
    • 2017-11-11
    • 2020-11-17
    • 2016-04-07
    相关资源
    最近更新 更多