Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Proper Way of Releasing COM Objects in .NET

4.93/5 (7 votes)
2 Aug 2011CPOL1 min read 49.8K  
Please let me suggest that FinalReleaseComObject is not the way to go. If you write structured code, you should never need it. Strictly following Microsoft Patterns & Practices:1) Declare & instantiate COM objects at the last moment possible.2) ReleaseComObject(obj) for ALL...
Please let me suggest that "FinalReleaseComObject" is not the way to go. If you write structured code, you should never need it.

Strictly following Microsoft Patterns & Practices:

1) Declare & instantiate COM objects at the last moment possible.
2) ReleaseComObject(obj) for ALL objects, at the soonest moment possible.
3) Always ReleaseComObject in the opposite order of creation.
4) NEVER call GC.Collect() except when required for debugging.

All of these things are documented on MSDN. Upon following these simple rules, .NET will optimize garbage collection along the way, minimizing memory/garbage load, and improving your overall application performance.

WARNING:
GC.Collect will stop all .NET process in the OS to collect garbage. With each call to GC.Collect, you may promote garbage from Generation 0 to Generation 1 and then to Generation 2. Once your garbage reaches Generation 2, you must terminate your process to recover memory.

Finally, your code may require calling GC.Collect to get around leaky code. You can unknowingly leak hidden COM objects into garbage just by taking legitimate coding shortcuts. For example:

Imagine a COM function that does work, and returns a COM object.

C#
(comClass.comObject) myCom.ProcessError(errorNumber);


Your code doesn't want the resulting object, it just wants to process the error:

C#
myCom.ProcessError(5);
Marshal.ReleaseComObject(myCom);


The returned COM object is sent to .NET garbage, keeping a handle to myCom from garbage.


Until GC naturally occurs, myCom will not be fully released. This is why so many people need to force object destruction using FinalReleaseComObject() and GC.Collect(). Both are required for dirty Interop code.

A CLEAN version of this code:

C#
Marshal.ReleaseComObject( myCom.ProcessError (5) ); //Release returned object
Marshal.ReleaseComObject( myCom);


There are many other shortcuts where you ignore items in collections, and when you follow certain COM objects chains where you can leak intermediate objects. Again, please refer to Microsoft Patterns and Practices.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)