我提前道歉;这是一个很长的问题。我已经尽可能地简化了,但它仍然比我想看到的要冗长一些。
在一些遗留代码中,我们有一个 VB6 集合。此集合通过 .Add 方法添加对象并通过 .Remove 方法删除它们。但是,通过跟踪我可以看到,有时当调用 .Remove 时,似乎没有调用对象的类终止。但这并不一致;它很少发生,我无法隔离它未能触发类终止的情况。
考虑以下演示代码:
Option Explicit
Private Const maxServants As Integer = 15
Private Const className As String = "Master"
Private Sub Class_Initialize()
Debug.Print className & " class constructor "
Set g_coll1 = New Collection
Dim i As Integer
For i = 1 To maxServants
Dim m_servant As Servant
Set m_servant = New Servant
m_servant.InstanceNo = i
g_coll1.Add Item:=m_servant, Key:=CStr(i)
Debug.Print "Adding servant " & m_servant.InstanceNo
Next
End Sub
Private Sub Class_Terminate()
Dim i As Integer
For i = maxServants To 1 Step -1
g_coll1.Remove (CStr(i))
Next
Debug.Print className & " class terminator "
Set g_coll1 = Nothing
Exit Sub
End Sub
和
Option Explicit
Private Const className As String = "Servant"
Private m_instanceNo As Integer
Private Sub Class_Initialize()
m_instanceNo = 0
Debug.Print className & " class constructor "
End Sub
Public Property Get InstanceNo() As Integer
InstanceNo = m_instanceNo
End Property
Public Property Let InstanceNo(newInstanceNo As Integer)
m_instanceNo = newInstanceNo
End Property
Private Sub Class_Terminate()
Debug.Print className & " class terminator for " & CStr(Me.InstanceNo)
End Sub
这是测试工具代码:
Option Explicit
Global g_coll1 As Collection
Public Sub Main()
Dim a As Master
Set a = New Master
End Sub
现在,对于每次运行,Servant 的 class_terminate 总是被调用。而且我在生产代码中看不到任何应该保留引用集合中的对象的内容。
1.) 有什么方法可以强制类在 Remove 上终止?也就是说,我可以调用 Obj.Class_Terminate 并确保它每次都能正常工作吗?
2.)在我的生产代码(和我的小测试应用程序)上,这些类被标记为“Instancing - 5 MultiUse”。我意识到这可能是某种线程问题;有没有一种有效的方法来证明(或反驳)多线程是这个问题的原因——我可能会添加某种跟踪或我可能执行的某种其他类型的测试?
编辑:根据 MarkJ 在下面的富有洞察力的评论,我应该补充一点,上面发布的测试和生产代码都是 ActiveX exe 的——我询问多线程的部分原因。