1
votes

Hi I have a project migrated from VB6 to C# and using many Interop COM objects written in either C++ or VB6 by other team. The problem is when we finish one application (windows), sometimes it stays in memory so we have to kill it using Task Manager. But the same program is a part of web suit which can be used as a service. So each time a user use this using a webpage it stays in memory and keep holding the memory. We use COM objects in this way.

Interop.Sales.SomeClass Obj = new Interop.Sales.SomeClass();

if (obj.prop1.Prom2[1].item[0].prop == something)

....

My question is should we have to just clean the root object at the end like this

System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null; // will it release all underlying objects created when accessing them?

or have to clean its each child object created in memory when accessing? like

System.Runtime.InteropServices.Marshal.ReleaseComObject(obj.prop1.Prom2[1].item[0].prop);
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj.prop1.Prom2[1].item[0]);
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj.prop1.Prom2[1]);
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj.prop1);
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;

My problem is that the project have more than 15000 lines of code and COM Interop objects are used at many places using the same way. If I have to follow the second way then it could be a very long and risky task. Please guide me the best solution to release all objects in COM Interop.

Thanks

QF

2
No, neither will actually release the object. "Long and risky" is a correct description of the exercise. You are competing with a machine that never gets this wrong, it is merely a bit slow at getting around to it. When it does get it wrong then there is something seriously wrong in your program. Beyond debugging and unexpected process termination, usually a deadlock in the finalizer thread. Not something you'd ever want to ignore. - Hans Passant

2 Answers

2
votes

I would suggest you use:

if (pSrvLocPnt_new != null)
{
    while (Marshal.ReleaseComObject(pSrvLocPnt_new) > 0) { }
    pSrvLocPnt_new =null;
}

instead of:

System.Runtime.InteropServices.Marshal.ReleaseComObject(obj.prop1);

One more thing you need to take care of: just make sure that you are releasing the COM object as soon as they aren't needed anymore. If you are using the COM object in a loop, make sure that at the end of the loop, you release them, and never use Marshal.FinalReleaseComObject() it may give you an exception.

Hope this helps you.

0
votes

While your question is more generically asked in regards to COM, the answer for the question about using Excel Interop/COM at the following link tells you everything you need. Short answer is, no, there are no shortcuts. Make sure your COM objects are cleaned up properly and as soon as possible.

Invoking and cleaning up after COM