.NET和COM互操作性:从.NET客户端版本COM [英] .NET and COM Interoperability : release COM from .NET client

查看:153
本文介绍了.NET和COM互操作性:从.NET客户端版本COM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个COM对象(非托管)和.NET客户端。

Assume I have a COM object (unmanaged) and .NET Client.

是否有必要从.NET客户端 Marshal.FinalReleaseComObject 方法以释放COM对象调用?

Is it necessary to call from the .NET client Marshal.FinalReleaseComObject method in order to release the COM object?

推荐答案

A 修改的是和否。

首先,请记住, ReleaseComObject的的自动降低实际COM对象参考计数。相反,它降低了内部的RCW计数。 (每次的一样的COM对象从COM-移动> NET它将使用的一样的RCW并且由一个递增RCW计数器)。同样, FinalRelaseComObject 也影响了RCW counterand有效地将其设置为0。这是当RCW计数器变为0的.NET将减少的实际的COM参考计数。

First off, bear in mind that ReleaseComObject does not automatically decrease the real COM object ref-count. Rather it decreases the internal RCW counter. (Every time the same COM object is moved from COM->NET it will use the same RCW and increment the RCW counter by one.) Likewise, FinalRelaseComObject also affects the RCW counterand effectively "sets it to 0". It is when the RCW counter goes to zero that .NET will decrease the actual COM ref-count.

因此​​,是,,但修改这些规则

So, "yes", but modified for these rules:

  1. 每次的从COM-对象跨> NET它的应该的有 ReleaseComObject的但不 FinalReleaseComObject ,在它被调用。也就是说,它应该被调用的一旦的每次对象杂交,即使它导致一个基准等于RCW
  2. 引用的RCW的数量(这仅仅是一个代理包装)并不重要;只有与时俱进对象已越过边界。见规则#1。 (重要的是要控制引用和谁保持他们来说是重要的,但最糟糕的情况发生在这种情况下使用独立RCW这是的的异常没有什么区别的比使用已释放流。)
  1. Every time an object cross from COM->NET it should have ReleaseComObject, but not FinalReleaseComObject, invoked upon it. That is, it should be invoked once for each time the object crosses, even if it results in a reference-equals RCW.
  2. The number of references to the RCW (which is just a proxy wrapper) do not matter; only the times the object has crossed the boundary. See rule #1. (It is important to control references and who keeps them, but the "worst" that happens in this case is an exception from using a "detached RCW" which is no different than using a Disposed stream.)

我说的上述规则和没有 FinalReleaseComObject ,因为RCW对象被缓存在身份代理,所以使用 FinalReleaseComObject 会影响COM-> NET口岸,你甚至不知道! (这是坏的,在这一点上,我完全同意JaredPars答案。)

I say the rules above and not FinalReleaseComObject because the RCW objects are cached in an identity proxy, so using FinalReleaseComObject will affect COM->NET boundary crossings you didn't even know about! (This is bad and, on this point, I entirely agree with JaredPars answer.)

不的是,当RCW被收回的(终结的叫法),它会自动释放的COM引用(有效地调用 FinalReleaseComObject 本身)。请记住,因为只有一个RCW对象,这意味着它的永远的,只要有对它的引用在.NET中回收。如果RCW被回收有没有问题的,因为,从上面,有没有更多的引用所述RCW从而.NET知道它可以由一个减小的COM裁判计数(这可能会导致在COM反对被破坏)。

And "no" in that, when an RCW is reclaimed (the finalizer is called), it will automatically "release" the COM reference (effectively call FinalReleaseComObject on itself). Remember that since there is only one RCW object this means that it will never be reclaimed as long as there is a reference to it in .NET. If the RCW is reclaimed there is no problem because, from above, there are no more references to said RCW and thus .NET knows it can decrease the COM ref-count by one (which may cause the COM object to be destroyed).

然而,因为.NET GC是挑剔和不确定性的,靠这种行为意味着对象的寿命不控制。这可能会导致的许多的与Outlook对象模型中工作时,例如微妙的问题。 (这可能是不太容易与其他COM服务器的问题,但OOM确实在内部对象的搞笑缓存,这是很容易得到的时候没有控制寿命明确了项目已被修改例外。)

However, since the .NET GC is finicky and non-deterministic, relying on this behavior means that object-lifetimes are not controlled. This can cause many subtle issues when working with the Outlook Object Model, for instance. (It may be less prone to issues with other COM servers, but the OOM does funny "caching" of objects internally. It is easy to get a "Item has already been modified" exception when not controlling lifetimes explicitly.)

在我的code我有一个支持的IDisposable A ComWrapper 类。这让我通过与周围的明确终身所有权 NET>。我切换到这种做法和许多的问题前手后,有极少数的问题(几乎没有,其实)在我的Outlook加载项的发展。而缺点是COM-> NET的边界需要确定,但一旦是,在内部所有的生存期正确处理。

In my code I have a ComWrapper class that supports IDisposable. This allows me to pass around RCW objects obtained from the COM->NET with clear lifetime ownership. I have had very few issues (almost none, actually) in my Outlook-Addin development after switching to this approach and numerous issues before hand. The "downside" is that COM->NET boundary needs to be determined, but once that is, then internally all the lifetimes are correctly handled.

快乐编码。

这篇关于.NET和COM互操作性:从.NET客户端版本COM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆