Je m'excuse d'avance; C'est une longue question. J'ai essayé de simplifier autant que je peux mais c'est encore un peu plus long que ce que je voudrais voir.VB6 Collection Supprimer Ne pas déclencher Class_Terminate
Dans certains codes hérités, nous avons une collection VB6. Cette collection ajoute des objets via la méthode .Add et les supprime via la méthode .Remove. Cependant, via le traçage, je peux voir que parfois lorsque le .Remove est appelé, il apparaît que la classe terminée pour l'objet n'est pas appelée. Mais ce n'est pas cohérent. cela n'arrive que rarement et je ne peux pas isoler les circonstances dans lesquelles il ne parvient pas à terminer la classe.
Tenir compte du code de démonstration suivante:
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
et
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
ce qui est le code de harnais de test:
Option Explicit
Global g_coll1 As Collection
Public Sub Main()
Dim a As Master
Set a = New Master
End Sub
Maintenant, pour chaque course, le Class_Terminate du Serviteur est toujours invoqué. Et je ne vois rien dans le code de production qui devrait garder l'objet dans la collection référencée.
1.) Y a-t-il un moyen de forcer la fin de la classe sur le Remove? Autrement dit, puis-je appeler Obj.Class_Terminate et être assuré qu'il fonctionnera à chaque fois? 2. Sur mon code de production (et ma petite application de test) les classes sont marquées "Instancing - 5 MultiUse". Je réalise que cela peut être une sorte de problème de threading; Existe-t-il un moyen efficace de prouver (ou réfuter) que le multi-threading est la cause de ce problème - une sorte de traçage que je pourrais ajouter ou un autre type de test que je pourrais effectuer?
EDIT: Par des commentaires perspicaces de MarkJ ci-dessous, je dois ajouter que le test affiché ci-dessus et le code de production sont les deux exe's ActiveX - une partie de la raison pour laquelle je demande à propos de mulit-threading.
Vous pouvez vérifier si l'objet est toujours référencé après l'avoir retiré de la collecte en consultant son compte de référence à l'aide d'un hack: http://www.vb-helper.com/howto_get_reference_count.html –
@Pavel, merci pour le lien . –