3

我正在做单元测试。

我的解决方案中有 2 个项目 1 是库项目,1 是测试项目。图书馆项目有一些 com 组件。测试项目是测试库项目中的功能。这些库函数正在使用这些 com 对象。

第一个单元测试成功执行,但是当我尝试按顺序执行 2 个单元测试时,在第二个单元测试中,当我尝试访问这些 com 对象时,我收到错误“无法使用已与其底层 RCW 分离的 COM 对象”。

4

1 回答 1

1

这意味着有人使用Marshal.ReleaseComObject不正确,或者更糟糕的是,使用Marshal.FinalReleaseComObject. 第一个单元测试通过这种相关的副作用影响第二个单元测试,可能是在拆卸方法中。解决此问题的第一步是准确找出导致异常的对象/访问/位置。

发生这种情况是因为在已释放 COM 对象(COM ref-count 设置为 0)的 RCW 上调用方法,这意味着ReleaseComObject已调用太多次或FinalReleaseComObject根本没有调用。

如果您拥有一个 RCW 对象(已将其“带入 CLR”),并且它的生命周期已到,ReleaseComObject则可以(将变量设置null为也可以避免再次使用它)。使用FinalReleaseComObject通常永远不会好,因为它不可能正确地跟踪生命周期。诀窍是要记住,单个 RCW 对象表示COM 对象已“带入 CLR”并具有内部(非 COM)计数器的一次或多次。

许多情况下,GC 将在其终结器运行时正确处理 RCW 清理。并且当时 RCW 不是强可达的,因此无法生成异常。在需要严格控制COM 生命周期的情况下,使用显式ReleaseComObject[仅] 是必需的/有用的(考虑 COM 对象的“共享” )。在处理 Microsoft Office 产品的加载项开发时,这很重要:)Dispose

.NET 和 COM 互操作性中还有其他详细信息(在我的回答中):从 .NET 客户端释放 COM和一篇反文章ReleaseComObject 被认为是危险的

快乐编码。

于 2012-04-16T08:54:30.640 回答