问题描述
我知道基本的差异 ReleaseComObject的
只值减少了一些柜台, FinalReleaseComObject
降低到零。
I know the basic difference as ReleaseComObject
only decreases some counter by one and FinalReleaseComObject
decreases it to zero.
所以,我通常听到的是,调用 FinalReleaseComObject
,因为你是确保COM对象是真正的释放。
So what I usually hear is, call FinalReleaseComObject
because then you are sure that the COM object is really released.
但是,这让我不知道,有一点这个柜台吗?难道你不打破这一机制,如果你总是叫 FinalReleaseComObject
。如果计数器不是的一个的,然后调用 ReleaseComObject的
,是不是有可能是一个原因吧?
But this makes me wonder, there is a point to this counter right? Aren't you breaking that mechanism if you always call FinalReleaseComObject
. If that counter is not one before you call ReleaseComObject
, is there not probably a reason for it?
什么会导致它是大于1时,它不应该是什么?
What could cause it to be higher than one when it should not be?
在此先感谢。
PS:我的COM的经验只包括使用Excel互操作的。不知道这个问题是局部的域(即办公室互操作之外, FinalReleaseComObject
不经常使用)。
PS: My COM experience only consists of using Excel Interop. Not sure if this question is local to that domain (i.e. outside Office Interop, FinalReleaseComObject
is not often used).
丹提到会谈有关使用文章 ReleaseComObject的
时,即可大功告成。当我从文章明白了,这是正常的方式。我认为,如果你经常这么做,应该很好地工作。在注释笔者文章建议有人叫 ReleaseComObject的
在循环中,直到它真正解除(文章是从2006年,所以这是类似物调用 FinalReleaseComObject
)。但他也指出,这可能是危险的。
The article Dan mentioned talks about using ReleaseComObject
when you're done. As I understand from the article, this is the normal way. I think that if you do this consistently it should work fine. In a comment to the article the author suggests someone to call ReleaseComObject
in a loop until it is really released (the article is from 2006, so this is analogues to calling FinalReleaseComObject
). But he also states that this could be dangerous.
如果你真的想在RCW调用Release()时在code某一点,你可以在一个循环中调用ReleaseComObject的(),直到返回值达到零。这将确保RCW将调用Release()。但是,如果你这样做的,予以警告,当其他托管引用尝试使用RCW,这将导致异常。
这使我相信,这确实是的没有的一个好主意,总是叫 FinalReleaseComObject
,因为你可以在其他地方引起异常。正如现在我明白了,你应该只调用这个,如果你是绝对相信你可以的。
This leads me to believe that it is indeed not a good idea to always call FinalReleaseComObject
, as you can cause exceptions elsewhere. As I see it now, you should only call this if you are absolutely sure that you can.
不过,我已经在这个问题上缺乏经验。我不知道我怎么能肯定。如果计数器增加时,它不应该是,是不是更好地解决这个问题?如果是这样,那么我会说 FinalReleaseComObject
更是一个黑客不是最好的做法。
Still, I have little experience in this matter. I don't know how I can be sure. If the counter is increased when it should not be, is it not better to fix that problem? If so, then I would say FinalReleaseComObject
is more of a hack than a best practice.
推荐答案
有些preamble ...
Some preamble...
一个运行时可调用包装(RCW),仅对其包装的非托管COM接口调用IUnknown.AddRef一次。然而,RCW还维护管理的参考有向RCW本身的数目的一个单独的计数。正是这种独立是通过调用Marshal.ReleaseComObject的递减托管引用计数。当管理引用计数达到零时,RCW IUnknown.Release一旦托管COM接口调用。
A Runtime Callable Wrapper (RCW) only calls IUnknown.AddRef once on the unmanaged COM interface that it wraps. However, an RCW also maintains a separate count of the number of managed references there are to the RCW itself. It is this separate count of managed references that is decremented by a call to Marshal.ReleaseComObject. When the count of managed references reaches zero, the RCW calls IUnknown.Release once on the unmanaged COM interface.
Marshal.FinalReleaseComObject在托管引用计数为零,单呼,从而立即调用包装的非托管IUnknown.Release方法(假设管理引用计数是不是已经为零)。
Marshal.FinalReleaseComObject takes the managed reference count to zero with a single call, and thus invokes the wrapped unmanaged IUnknown.Release method immediately (assuming that the managed reference count was not already zero).
那么,为什么有两种Marshal.ReleaseComObject的和Marshal.FinalReleaseComObject?调用Marshal.FinalReleaseComObject只是避免了不得不写一个循环调用Marshal.ReleaseComObject的反复,直到它返回0,当你想表明你已经的真的使用COM对象的现在。
So why have both Marshal.ReleaseComObject and Marshal.FinalReleaseComObject? Calling Marshal.FinalReleaseComObject simply avoids having to write a loop that calls Marshal.ReleaseComObject repeatedly until it returns 0 when you wish to indicate that you've really finished using a COM object now.
为什么要请使用Marshal.ReleaseComObject的还是Marshal.FinalReleaseComObject?有两个原因,我所知道的:
Why use either Marshal.ReleaseComObject or Marshal.FinalReleaseComObject? There are two reasons I'm aware of:
首先是要确保非托管资源(如文件句柄,存储器等)正在使用的包装的COM对象被尽快释放作为所得调用非托管IUnknown.Release的结果()方法。
The first is to ensure that unmanaged resources (such as file handles, memory etc.) being used by the wrapped COM object are freed as soon as possible as a result of the resulting call to the unmanaged IUnknown.Release() method.
二是要保证线程调用非托管IUnknown.Release()方法是你的控制之下,而不是终结器线程。
The second is to ensure that the thread calling the unmanaged IUnknown.Release() method is under your control, and not the finalizer thread.
在不调用其中任一元帅方法,该RCW的终结会的最终的调用非托管IUnknown.Release()方法一段时间RCW已经被垃圾回收后。
Without calls to either of these Marshal methods, the RCW's finalizer will eventually call the unmanaged IUnknown.Release() method some time after the RCW has been garbage collected.
有关佐证的详细信息,请参阅Visual C ++团队博客条目混合确定性和不确定性清理
For corroborative details, see the Visual C++ Team blog entry Mixing deterministic and non-deterministic cleanup
这篇关于为什么使用FinalReleaseComObject代替ReleaseComObject的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!