あらかじめお詫び申し上げます。これは長い質問です。できる限り単純化しようとしましたが、それでも、見たいと思うよりも少し長くなります。
一部のレガシー コードには、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 のものであることを追加する必要があります。これは、マルチスレッドについて質問する理由の一部です。