代码之家  ›  专栏  ›  技术社区  ›  Onorio Catenacci

VB6集合删除不触发类终止

  •  4
  • Onorio Catenacci  · 技术社区  · 15 年前

    我事先道歉,这是个很长的问题。我试着尽可能简化,但它仍然比我想看到的要冗长。

    在一些遗留代码中,我们有一个vb6集合。此集合通过.add方法添加对象,并通过.remove方法删除它们。但是,通过跟踪,我可以看到,有时当调用.Enter时,似乎没有调用对象终止的类。但它并不一致,它只发生很少,我不能孤立的情况下,它不能解雇类终止。

    请考虑以下演示代码:

    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.)是否有任何方法强制类在移除时终止?也就是说,我可以调用Obj.CasyType并保证它每次都能工作吗?

    2.)在我的生产代码(和我的小测试应用程序)中,这些类被标记为“instancing-5 multiuse”。我意识到这可能是某种线程问题;是否有有效的方法来证明(或反驳)多线程是导致此问题的原因——我可能添加某种跟踪或执行某种其他测试?


    编辑:根据下面markj有见地的评论,我应该补充一下上面发布的测试和生产代码都是activex exe的——这也是我询问mulit线程的部分原因。

    1 回复  |  直到 15 年前
        1
  •  3
  •   Ant    15 年前

    我们有一个类似的问题,但是我们可以在哪里跟踪对象的不终止性,从而找到应用程序中其他地方保存的实例。

    最后,我们不得不这样写终止方法:

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

    因此,无论何时您真希望该类被终止(即当调用GyCal1.Debug)时,也可以调用 Terminate 在被抓住的物体上。

    我认为你也可以让类终止公开,但在我看来这有点难看。

    关于你的观点(2),我认为这不太可能是一个线程问题,但我想不出一个好的证明/测试。我想您可以考虑的一件事是:您是否在应用程序中手动使用线程?VB6不会自动执行太多线程…(见下面的编辑)

    [ 编辑 ]markj告诉我们,显然作为activex应用程序构建意味着vb6 自动执行线程。因为我不熟悉,其他人将不得不探究这件事的含义!