Use the static
ReleaseComObject
method of the
Marshal
class:
int newRefCount = System.Runtime.InteropServices.Marshal.ReleaseComObject(COMObj
);
where COMObj
is a reference to the runtime
callable wrapper (RCW) of a COM object.
If the COM object is holding on to resources that need to be released
in a timely manner, we will want to decrement the reference count on
the COM object as quickly as possible, once we’ve
finished using the COM object and have set it to
null
. The GC needs to run in order to collect the
unreferenced RCW around our COM object, thereby decrementing the
reference count on the COM object. Unfortunately, there is no
guarantee that the GC will run in order to collect the RCW anytime in
the near future.
To solve this problem, we could call GC.Collect
ourselves to try to free the RCW, but this might be overkill.
Instead, use the ReleaseComObject
method to
manually force the RCW to decrement its reference count on the COM
object without having to force a collection to occur.
The static ReleaseComObject
method returns an
int
indicating the current reference count
contained in the RCW object after this method has finished
decrementing its reference count. Remember that this method
decrements the reference count contained in the RCW, not the COM
object’s reference count. When the RCW reference
count goes to zero, it releases its COM object. At this point, the GC
can collect the RCW.
Care must be used when calling the
ReleaseComObject
method. Misuse of this method can
cause a COM object to be released by the RCW too early. Since the
ReleaseComObject
method decrements the reference
count in the RCW, you should call it no more than one time for every
object that contains a pointer to the RCW. Calling it multiple times
might cause the RCW to release the COM object earlier than expected.
Any attempt to use a reference to an RCW that has had its reference
count decremented to zero results in a
NullReferenceException
exception. The RCW might not have
been collected yet, but its reference to the COM object has been
terminated.
See Recipe 3.29 and Recipe 3.36; see the “Marshal.ReleaseComObject Method” topic in the MSDN documentation.