Ainz
Ainz
CC#
Created by Ainz on 8/12/2022 in #help
[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