прошу прощения заранее; это длинный вопрос. Я пытался упростить столько, сколько смогу, но это все еще более многословно, чем мне хотелось бы видеть.
В каком-то устаревшем коде у нас есть коллекция 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
Теперь для каждого запуска всегда вызывается class_terminate Servant. И я не вижу ничего в производственном коде, который бы содержал ссылку на объект в коллекции.
1.) Есть ли способ принудительно завершить класс при удалении? То есть я могу вызвать Obj.Class_Terminate и быть уверенным, что он будет работать каждый раз?
2.) В моем рабочем коде (и моем небольшом тестовом приложении) классы помечены как «Instancing - 5 MultiUse». Я понимаю, что это может быть какая-то проблема с многопоточностью; Есть ли эффективный способ доказать (или опровергнуть), что причиной этой проблемы является многопоточность - какой-то вид трассировки, который я мог бы добавить, или какой-то другой вид теста, который я мог бы выполнить?
РЕДАКТИРОВАТЬ: В соответствии с проницательным комментарием MarkJ ниже, я должен добавить, что опубликованный выше тест и производственный код являются ActiveX exe - одна из причин, почему я спрашиваю о многопоточности.