views:

436

answers:

8

Is it really necessary to release COM components from Office PIA, when you don't need them anymore by invoking Marshal.ReleaseComObject(..)?

I found various and contradictory advices on this topic on the web. In my opinion, since Outlook PIA is always returning a new references to its interfaces as returning values from its methods, it is not necessary to explicitly release it. Am I right?

+1  A: 

There are some good practices here using a managed wrapper..worth checking out..

Gulzar
Thanks, it is a good article. But, I need to know do I need to explicitly release COM component from existing Office PIA, not to make my own wrapper.
Nenad
A: 

Maybe it's just my superstition, but I decided to explicitly release the Office PIA via Marshal.ReleaseComObject() because when my application crashed, the references to Excel and Word were staying open. I didn't dig too deep into why (stupid deadlines), but releasing them as part of my class's dispose pattern fixed that problem.

Robert S.
+2  A: 

PIAs are .NET interop wrappers. This means that in the object's destructor (or Dispose - I can't remember) will automatically handle its reference count. The trick is that some references won't be released until the garbage collector is executed. It depends on what the COM object instantiates. For instance, a COM object that opens database cursors will keep those cursors alive in memory until the reference count on those cursors is released. With the .NET/COM interop, the references aren't released until the garbage collector executes or you explicitly release the reference using Marshal.ReleaseComObject (or FinalReleaseComObject).

I personally haven't worked with the Microsoft Office PIAs, but under most circumstances, you shouldn't have to explicitly release the references. It is only when your application starts to lock other resources or crash that you should start being suspicious about dangling references.

EDIT: If you run into a situation where you do need to cleanup COM/Interop objects, use Marshal.FinalReleaseComObject - which takes the reference count all the way to zero instead of just decrementing by one - and set the object reference to null. You can explicitly force garbage collection (GC.Collect) if you really want to be safe, but be careful of doing GC too often as it does invoke a noticeable performance hit.

j0rd4n
A: 

You do need to do so if you want the instance of the Office application to exit, as described in this post.

And it's difficult to get it right in all but the most simple scenarios.

Joe
But, in the case that I omit a clean up code, nothing bad happens. Outlook even closes faster in that case, and I found a few articles on the web that state that it's not necessary to release a Outlook COM objects.
Nenad
+1  A: 

With Microsoft Office, in general, you do need to explicitly release your references, which can be safely done in two stages:

(1) First release all the minor object to which you do not hold a named object variable via a call to GC.Collect() and then GC.WaitForPendingFinalizers(). (You need to call this twice, if the objects involved could have finalizers, such as when using Visual Studio Tools for Office (VSTO).)

(2) Then explicitly release the objects to which you hold a named variable via a call to Marshall.FinalReleaseComObject() on each object.

That's it. :-)

I discussed this in more detail in a previous post, along with a code example.

Mike Rosenblum
Mike, would you comment this one then: http://stackoverflow.com/questions/159313/runtime-callable-wrapper-rcw-scope-process-or-application-domain
Sunny
A: 

My experience shows that you have to, otherwise (at least Outlook) the application may not shut down at all.

But this opens another can of worms, as it looks like the RCWs are per process, thus you can break some other addin, which happens to have a reference to the same object.

I have posted a related question here, but I still have no clear answer. I'll edit this post once I know more.

Sunny
A: 

There's one simple rule about .Net/COM interop - When in doubt, always Release(). :-)

Franci Penov
A: 

For VS 2010, see Marshal.ReleaseComObject Is Considered Dangerous.

TrueWill