Frage

ich im Voraus entschuldigen; dies ist eine lange Frage. Ich habe versucht, so viel zu vereinfachen, wie ich kann, aber es ist immer noch ein bisschen mehr langatmig als ich egal, Sie zu sehen.

In einigem Legacy-Code haben wir eine VB6 Sammlung bekommen. Diese Sammlung fügt Objekte über die .Add Methode und entfernt sie über die .Remove Methode. Doch über Tracing kann ich, dass manchmal sehen, wenn die .Remove aufgerufen wird es scheint, dass die Klasse beenden für das Objekt wird nicht aufgerufen. Aber es ist nicht konsistent; es geschieht nur selten, und ich kann die Umstände, unter denen sie die Klasse nicht nicht isoliert Feuer zu beenden.

Betrachten Sie die folgende Demonstration 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

und

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

und das ist der Test-Harnisch-Code:

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

Nun, für jeden Durchlauf wird der Class_Terminate von Servant immer aufgerufen. Und ich kann nicht alles in der Produktion Code sehen, die das Objekt in der Auflistung verwiesen halten sollte.

1.) Gibt es eine Möglichkeit, die Klasse zu zwingen, auf dem Entfernen beenden? Das heißt, kann ich Obj.Class_Terminate anrufen und sichergestellt wird, jedes Mal arbeiten?

2) Auf dem Produktionscode (und meinen kleinen Test-App) werden die Klassen "Instancing - 5 MultiUse" gekennzeichnet.. Ich weiß, das eine Art von Threading-Problem sein kann; ist es ein effektiver Weg (oder widerlegen), dass Multi-Threading ist die Ursache dieses Problems zu beweisen - eine Art Tracing mich hinzufügen oder eine andere Art von Test könnte ich durchführen könnte


EDIT: Per MarkJ des aufschlussreichen Kommentar unten, soll ich hinzufügen, dass der Test über und den Produktionscode geschrieben ist beide ActiveX exe's - ein Teil des Grundes, warum ich über Mulit-Threading frage

.
War es hilfreich?

Lösung

Wir hatten ein ähnliches Problem, aber wo wir die Nicht-Beendigung der Objekte verfolgen konnten auf eine Instanz an anderer Stelle in unserer Anwendung zu sein, nach unten gehalten wird.

Am Ende hatten wir unsere Kündigung Methode wie folgt zu schreiben:

Private Sub Class_Terminate()
    Terminate
End Sub

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

Also, wenn Sie wollte wirklich die Klasse beendet werden (das heißt, wenn Sie g_coll1.Remove nennen), können Sie auch Terminate auf dem gehaltenen Objekt aufrufen.

Ich denke, dass Sie auch Class_Terminate öffentlich machen könnten, aber das ist ein bisschen hässlich meiner Meinung nach.

Re Ihren Punkt (2), halte ich es für sehr unwahrscheinlich ist, ein Threading-Problem zu sein, aber ich kann einen guten Beweis / Test aus der Spitze von meinem Kopf nicht denken. Ich nehme ein sehr recht, was man beachten kann, ist: Verwenden Sie manuell Einfädeln in Ihrer Anwendung? VB6 nicht viel tun Einfädeln automatisch ... (siehe bearbeitet unten)

[ Bearbeiten ] MarkJ uns sagt, dass offenbar als ActiveX-Anwendung erstellen bedeutet, dass VB6 hat automatisch tun Threading. Jemand anderes wird die Tragweite dieses erforschen müssen, da ich nicht mit ihm vertraut war!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top