I am instantiating a COM object from a VBA script in excel as defined in a C# dll. The C# class I instantiate has a finalizer that performs garbage collection, notably other MS Office objects it references, which I should see appear and disappear in the task manager. In fact, the unit tests demonstrate that an Office process appears when the dll is called, and goes away when it is finished.
When the dll is called from the VBA, I have noticed that the processes remain open after the VBA function ends, i.e. the object is notcleaned up after being called, which leads me to believe that VBA does not release the COM object.
My function looks something like this:
Function Raz(inp As String)
Dim o: Set o = CreateObject("foo.bar")
o.InputFields.FirstInput = inp
o.Update
Raz = o.OutputFields.FirstOutput
End Function
I have added the following line at the end of the function in order to resolve the issue:
set o = Nothing
However, the resources in my COM process remain after execution and completion of my VBA script. How do I garbage collect my COM objects from VBA without manually creating a dispose call?
In VBA the command to release an object is
You have a weak reference to the created object, Raz function return value, that maintains the object instance.
Variable o is automatic and referenced object is automatically set to nothing when function returns, but you are assigning value to Raz and probably to client code so the instanced value is not disposed on function return.
Furthermore, if the object, as it happens, reference a user control, you probably can't unload the user form containing it.
COM will keep processes in memory for a while after the last reference is gone, just in case you want to create another object requiring the same process soon afterwards.
The theory is that process creation is very slow and expensive, and you might inadvertently write a loop or something that does this:
You wouldn't want Windows thrashing around killing and launching processes endlessly in the loop.
Eventually they go away.