【发布时间】:2010-12-07 03:14:51
【问题描述】:
我有一个托管对象,它调用 COM 服务器来分配一些内存。托管对象必须在托管对象消失之前再次调用 COM 服务器以释放该内存以避免内存泄漏。此对象实现 IDisposable 以帮助确保进行正确的内存释放 COM 调用。
如果Dispose 方法没有被调用,我希望对象的终结器释放内存。问题是,终结的规则是你不能访问任何引用,因为你不知道在你之前已经被 GC 和/或终结的其他对象。这使得唯一可触摸的对象状态是字段(句柄是最常见的)。
但是调用 COM 服务器需要通过运行时可调用包装器 (RCW) 来释放内存,因为我有一个 cookie 来存储在字段中。 从终结器调用 RCW 是否安全(是否保证此时尚未被 GC 或终结)?
对于那些不熟悉终结的人,虽然终结器线程在运行时在托管 appdomain 的后台运行,但对于这些情况,触摸引用理论上是可以的,终结也发生在 appdomain 关闭时,并且 以任何顺序 -- 不仅仅是参考关系顺序。这限制了您可以假设从终结器中可以安全触摸的内容。任何对托管对象的引用都可能是“坏的”(收集的内存),即使该引用是非空的。
更新:我刚刚试了一下,得到了这个:
myassembly.dll 中出现“System.Runtime.InteropServices.InvalidComObjectException”类型的未处理异常
附加信息:已与其底层 RCW 分离的 COM 对象无法使用。
【问题讨论】:
-
COM 服务器上的一个方法(为什么有人会在 RCW 本身上调用 Dispose?如果这可能的话,我会感到惊讶)。