Ainz
[Solved] COM Interop, Garbage Collection, and Runtime Callable Wrapper object management [Answered]
Essentially, this question is going to boil down to: when is it appropriate to call
Marshal.FinalReleaseComObject()
and should it be manually called or should the Garbage Collector handle it? (I'm fully expecting an $itdepends answer for this question.)
Background: Apps at work interop with MS Excel and AutoCAD to drive these programs in-process and out-of-process. The .NET API around AutoCAD was written to function within the same process, not out-of-process. This forces any out of process .NET applications to utilize the ActiveX library to interop with AutoCAD. When application exits, the Excel and AutoCAD application processes are left open, visible to Task Manager., even though the application calls the .Quit();
method equivalents in each library.
COM and RCWs: From my understanding, the runtime will create a Runtime Callable Wrapper overtop COM interfaces so that it is treated as a managed object. I'm working with public static
fields within this code base, which makes them GC roots (?). If I'm understanding correctly, this means that the GC will not collect these instances until they are eligible for cleanup, effectively when nothing else is referencing them. Does this only happen when these variables are set to null
? (See https://www.add-in-express.com/creating-addins-blog/2013/11/05/release-excel-com-objects/) Is this essentially the reason why, my COM objects are never dereferenced and released by the process?
Excel Interop: The references to Excel.Worksheet
, Excel.Workbook
, and Excel.Application
are marked as public static
fields in the application code. When the application process exits, the application leaves the Excel process running in the background. If I call Marshal.FinalReleaseComObject
on my Excel COM variables, the process will exit normally when running the application. What here actually "holds" the live Excel process captive from being released? The .NET application that launched Excel should have been cleaned up by the .NET Garbage collector and any unmanaged objects would be cleaned up by the Windows operating system, right?
What exactly is the best practice? The Visual Studio team and some other users on sites like StackOverflow seem to state that manually releasing COM objects is something that shouldn't be done by the user and only handled by the garbage collector; but, others state that you must release COM objects when you are finished with them.
Against:
https://devblogs.microsoft.com/visualstudio/marshal-releasecomobject-considered-dangerous/#marshal-releasecomobject-a-problem-disguised-as-a-solution
https://stackoverflow.com/a/25135685
For:
https://www.add-in-express.com/creating-addins-blog/2013/11/05/release-excel-com-objects/
I've always read / have been told that COM Objects should always be manually released by the developer using Marshal.ReleaseComObject
and Marshal.FinalReleaseComObject
to ensure that the called application exits cleanly. And I feel like this is probably what should be done, but I'm wondering what side effects or gotchas I might end up encountering.39 replies