COM对象是否与RCW分离?

时间:2011-04-05 11:44:29

标签: c# com interop rcw

我正在尝试修复“已与其底层RCW分离的COM对象无法使用”错误,我认为导致它的原因是COM对象用于未实例化它们的线程。

我不允许进行太多的重构,并且由于对象应该在多个线程上可用,我想知道是否有办法找出它们是否已经在当前线程上创建,然后再对它们执行某些操作会导致上述错误。并且,如果他们没有,创建它们。

另外,我是这个互操作的新手,所以如果有人能够帮助我理解,我会非常感激:

一旦线程完成,COM对象会发生什么,为什么RCW仍然可用于另一个线程,即使它不再有COM对象(为什么不是null?)。另外,为什么它会导致该错误并同时在Marshal.IsCOMObject上返回true?

以下场景中带有引用计数以及包装器和内存的情况会发生什么:

  • 在主题A
  • 上创建COM对象x
  • 传递并将其保存在主题B
  • 在线程C
  • 上创建另一个x(或者,如果它是y?会发生什么?)
  • 传递并覆盖线程B上的x

1 个答案:

答案 0 :(得分:4)

  

线程完成后,COM对象会发生什么

COM对象被COM自动销毁。当另一个线程继续使用它时,将生成'已分离的COM对象'异常消息。你不能让线程退出。

显然,你有一个单线程的COM服务器,是迄今为止最常见的一种。它与创建它的STA线程具有亲缘关系。 COM确保自动将在另一个线程上进行的任何调用封送到创建该对象的线程。当线程消失时,这不再有效。还要注意你没有得到任何并发。

获得此异常的另一种方法是使用Marshal.ReleaseComObject()明确处理引用计数的错误。因为你应该得到MDA警告,所以并非不可能。