none
Release COM interface in C#

    Question

  • It may sound stupid, but I thought just set the COM interface object to null will release the COM interface object in C#.

    In my case, after I set the interface object to null, the COM server I created in C++ still stay on.

    I use the C++ clients to test and they work together well (after all clients terminated, the COM server shutdown itself).

     

    Anyone know what do I need to do in C# to release the interface of the COM server?

     

    Thanks in advance,

    Eric

    Friday, September 21, 2007 6:21 PM

Answers

  •  Sung M Kim wrote:

    Code Snippet

    while (Marshal.ReleaseComObject(comObject) > 0){}

     

    In .Net Framework 2.0 and later you can replace this loop with a single call on Marshal.FinalReleaseCOMObject() http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.marshal.finalreleasecomobject(vs.80).aspx

     

    You should be very careful when using either of these approaches.  Since they basically force the COM reference count to zero, they can have the effect of deactivating the COM server even when the server should not be deactivated - for example when other references to the COM object still exist. 

    Friday, September 21, 2007 9:24 PM
  • You can use a static method,  System.Runtime.InteropServices. Marshal.ReleaseComObject 

    Here is an example:

    Code Snippet

    while (Marshal.ReleaseComObject(comObject) > 0){}


    Basically, you are trying to release COM object(specified by "comObject" in the above example) until it has been released.

    It might not be an elegant solution but for now it's the only way that I know of.
    I hope anyone else has a better solution.


    Friday, September 21, 2007 6:42 PM

All replies

  • You can use a static method,  System.Runtime.InteropServices. Marshal.ReleaseComObject 

    Here is an example:

    Code Snippet

    while (Marshal.ReleaseComObject(comObject) > 0){}


    Basically, you are trying to release COM object(specified by "comObject" in the above example) until it has been released.

    It might not be an elegant solution but for now it's the only way that I know of.
    I hope anyone else has a better solution.


    Friday, September 21, 2007 6:42 PM
  • How are you instantiating this COM object?  Is it through the TLBIMP generated class?

     

    Friday, September 21, 2007 7:00 PM
  • Thank you, Sung.

    I'll try that.

     

    Friday, September 21, 2007 8:03 PM
  • Peter,

     

    Thanks for the reply. This is an EXE COM server. I just use IDE add Reference to add the COM interface.

    Inside I use comObj = new comServer.comObject(); to instantiate the interface.

    when I exit, I use comObj = null; to release the interface.

     

    Sung's comment (see reply) does work for one COM server. I still need to investigate other COM server's issue (3rd

    party's COM server, not mine).

     

    Hope you have better idea. Thanks,

    Eric

    Friday, September 21, 2007 8:43 PM
  •  Eric Chiang wrote:
    I thought just set the COM interface object to null will release the COM interface object in C#.

    In my case, after I set the interface object to null, the COM server I created in C++ still stay on.

     

    It will (or should, I haven't actually tried it for myself) but you may have to be patient. 

     

    Remember how .NET managed memory works.  When you set the COM interface object to null you make the interface object eligible for garbage collection, but the object doesn't get garbage collected right then and there.  The Garbage Collector tries to minimise overhead by running in the background which means you can never be sure when any particular object will be finalised (google for "non-deterministic finalization" for more discussion on this point).

     

    Eventually, the object gets finalized and garbage collected and during finalization the unmanaged IUnknown::Release() gets called.which should decrement the COM reference count.  Assuming the COM reference count reaches zero the COM object will terminate itself and your server should go away.


    So, if you wait long enough, setting the COM interface object to null should cause your COM server to (eventually) go away.  BUT, this assumes that:

    • you don't have other managed code references to the Inteface object (which would prevent finalization and garbage collection)
    • you don't have other Interface objects for the same COM server (which would keep the COM server alive)
    • your unmanaged COM reference count is correctly maintained so it does in fact reach zero when it should (otherwise the COM server again stays alive because the COM object appears to be in use).

    The ReleaseCOMObject can be used to accelerate this process by decrementing the COM reference count before finalization, but care should be taken when using this function.  See the section on Marshal.ReleaseCOMObject here: http://msdn2.microsoft.com/en-us/library/ms998551.aspx for further discussion.

     

    I use the C++ clients to test and they work together well (after all clients terminated, the COM server shutdown itself).

     

    Assuming these are native C++ clients, they will (presumably) be correctly calling IUnknown::AddRef() and IUnknown::Release() so when the reference count reaches zero the COM object deactivates itself.
    Friday, September 21, 2007 9:17 PM
  •  Sung M Kim wrote:

    Code Snippet

    while (Marshal.ReleaseComObject(comObject) > 0){}

     

    In .Net Framework 2.0 and later you can replace this loop with a single call on Marshal.FinalReleaseCOMObject() http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.marshal.finalreleasecomobject(vs.80).aspx

     

    You should be very careful when using either of these approaches.  Since they basically force the COM reference count to zero, they can have the effect of deactivating the COM server even when the server should not be deactivated - for example when other references to the COM object still exist. 

    Friday, September 21, 2007 9:24 PM