COM Object Cleanup

2019-05-10 14:37发布

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?

3条回答
一夜七次
2楼-- · 2019-05-10 15:07

In VBA the command to release an object is

Set o = Nothing
查看更多
Summer. ? 凉城
3楼-- · 2019-05-10 15:09

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.

查看更多
唯我独甜
4楼-- · 2019-05-10 15:11

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:

 While 1=1

      Set a = CreateObject(...)
      ' Later
      Set a = Nothing

 Wend

You wouldn't want Windows thrashing around killing and launching processes endlessly in the loop.

Eventually they go away.

查看更多
登录 后发表回答