Marshal.ReleaseComObject() vs. Marshal.FinalReleaseComObject()
很简单,不翻译了。
If you are using COM components on your .NET code, you might be already aware of the Marshal.ReleaseComObject and Marshal.FinalReleaseComObject, which are used to release the managed reference to Runtime Callable Wrapper (RCW) of the COM object.
If both are used to release COM objects from memory, and you are unsure which one to use, then this post will help you to learn the differences between the calls
.NET Framework is always a better choice managing your .NET objects. Once you are done, and the object that you are referring to goes out of scope, Garbage Collector automatically handles it to remove from memory. But that's not the same for unmanaged COM objects. Even though the scope of the instance variable goes out of it, but the reference still stays in memory as an RCW (Runtime Callable Wrapper).
Every time a COM interface pointer enters into the Common Language Runtime (CLR), it wraps it inside an RCW. Then the RCW keeps a reference count which is then incremented every time a COM interface pointer is mapped to it.
To release that memory instance, Marshal.ReleaseComObject method is used which enables you to force the RCW and decrements the reference count. When the reference count reaches to zero, the runtime releases all its references on that unmanaged COM object. Attempting to access that object afterwards, throws you an Exception.
Marshal.FinalReleaseComObject also does the same, but with a little difference. When you call Marshal.ReleaseComObject method, it releases one RCW reference and decrements the count by one. To remove all the managed references to a COM object, you need to call the Marshal.ReleaseComObject, the following way, in a loop until it returns '0' (zero) to free up the COM object:
while (Marshal.ReleaseComObject(obj) != 0) ;
But in case of Marshal.FinalReleaseComObject, you don't have to loop in to release all the associated references to RCW. Because, the method itself performs the same internally. If you check the original implementation of the System.Runtime.InteropServices.Marshal class, you will notice the following:
public static int FinalReleaseComObject (object o)
{
while (ReleaseComObject (o) != 0) ;
return 0;
}
So, after reading this, which one will you prefer? It's definitely the FinalReleaseComObject as it internally loops through the RCW to release all the instance references, until the count becomes '0' (zero). Isn't it? Call the ReleaseComObject only if it is absolutely required to perform on a single reference.
To learn further about the above two methods, checkout the MSDN reference: Marshal.ReleaseComObject and Marshal.FinalReleaseComObject. I hope that the above post was clear and easy to understand. Don't forget to read my other posts/articles published on this blog.
其实许多人建议不要使用Marshal这个类,因为可能会发生异常情况。但如果一定要用,看完了上面的洋文,你知道该用哪一个了么?
从这里抄来的:https://www.kunal-chowdhury.com/2017/08/marshal-release-com-object.html