It seems to me that this relates to writing Office add-in's via VSTO, which
is not the situation here.
When an Office applicatoin (such as Outlook) has an add-in written in .NET.
It runs within the context of the hosted CLR, so an AppDomain is created for
the add-in to run in.. When the add-in has completed its work, the
AppDomain within the hosted CLR ends, and thus the need to do any releasing
of COM objects (or GC cleanup for that matter), is moot.
The OP is not talking about this situation. AFAIK and based on everything
that I've read since 2002, is that when utilizing a COM object within the
context of a managed application (.NET Windows or ASP .NET), you MUST call
ReleaseCOMObject. This is because the situation is reversed. The RCW
exists in the SAME AppDomain as the main application, so just finishing the
work with the COM object won't mean the end of the AppDomain (because your
..NET application will still be running).
Think about this for a moment (or actually build a simple RCW project and
see for yourself).
1. The .NET code creates an instance of a COM object. This causes 3 items
to go into memory.
a. A variable on the managed stack.
b. A RCW instance on the managed heap (pointed to by the variable
mentioned above).
c. The COM object is instantiated and is in memory on the unmanaged
heap.
2. When your .NET application calls the .Quit() method of the COM object,
the program's UI may close, but the actual process remains in memory. Try
this yourself. You'll see that just calling .Quit() doesn't kill the
process (use the Task Manager to verify that the COM object's process is
still running).
3. If you call Marshall.ReleaseComObject(obj), you instruct the CLR to
release its (for lack of a better term) reference to the COM object on the
unmanaged heap, thus reducing its reference count to zero. In the COM
world, that is when the object is removed from memory.
4. Now that the underlying COM object has been successfully unloaded, we
still have our variable on the managed stack and our RCW on the managed
heap. At this point, it's .NET memory management as usual. You can set
your variable to null (Nothing in VB) if you like, but for a local variable,
that may not accomplish much, sice the variable will fall off the stack at
the end of the procedure anyway. Still though, it's not a bad practice to
do it.
5. Now we're just left with a managed object on the managed heap with no
references to it and the GC will clean it up if and when it deems it
necessary. No need to get the GC involved.
-Scott