VB6 Collection Remove Fire_Terminate class does not work

I apologize in advance; This is a long question. I tried to simplify as much as I can, but it is still a little longer than I would like to see.

In some obsolete code, we have a collection of VB6. This collection adds objects through the .Add method and deletes them using the .Remove method. However, through tracking, I see that sometimes when .Remove is called, it seems that the terminate class for the object is not being called. But it is consistent; this is rare, and I cannot isolate circumstances in which he cannot dismiss the class.

Consider the following demo code:

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 

and

 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 

and this is the test code for the wiring harness:

 Option Explicit Global g_coll1 As Collection Public Sub Main() Dim a As Master Set a = New Master End Sub 

Now for each start, class_terminate Servant is always started. And I don’t see anything in the production code, which should contain the object in the collection.

1.) Is there a way to force class termination in Remove? That is, can you call Obj.Class_Terminate and be sure that it will work every time?

2.) On my production code (and my small test application) the classes are marked "Instancing - 5 MultiUse". I understand that this may be some kind of thread problem; Is there an effective way to prove (or disprove) that the cause of this problem is multithreading - some kind of trace that I could add, or some other test that I could perform?


EDIT: Per MarkJ's insightful comment below, I have to add that the above test and production code are both ActiveX exe's - part of the reason I'm asking about mulit-threading.

+4
source share
1 answer

We had a similar problem, but where we could see if the objects that are inaccessible to the instance stored elsewhere in our application are stopped.

In the end, we had to write our Termination method as follows:

 Private Sub Class_Terminate() Terminate End Sub Public Sub Terminate() 'Do real termination in here' End Sub 

Therefore, whenever you really want the class to be completed (that is, when you call g_coll1.Remove), you can also call Terminate on the held object.

I think you can also make Class_Terminate publicly available, but it's a little ugly in my opinion.

Think about your point (2), I think this is unlikely to be a problem with threading, but I cannot come up with a good proof / test from the head. I suppose you might very well think: are you manually using threads in your application? VB6 does not do a lot of streaming automatically ... (see below)

[ Edit ] MarkJ tells us that apparently creating as an ActiveX application means that VB6 automatically runs threads. Someone else will have to study the consequences of this, since I was not familiar with it!

+3
source

All Articles