VB6集合不删除';t火灾等级(u)终止

VB6集合不删除';t火灾等级(u)终止,vb6,collections,class,destructor,Vb6,Collections,Class,Destructor,我事先道歉;这是一个很长的问题。我试着尽可能地简化,但它仍然比我想看到的要冗长一些 在一些遗留代码中,我们有一个VB6集合。此集合通过.Add方法添加对象,并通过.Remove方法删除对象。但是,通过跟踪,我可以看到有时调用.Remove时,似乎没有调用对象的类terminate。但这并不一致;这种情况很少发生,我无法隔离它无法触发类终止的情况 考虑以下演示代码: Option Explicit Private Const maxServants As Integer = 15 Private

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

在一些遗留代码中,我们有一个VB6集合。此集合通过.Add方法添加对象,并通过.Remove方法删除对象。但是,通过跟踪,我可以看到有时调用.Remove时,似乎没有调用对象的类terminate。但这并不一致;这种情况很少发生,我无法隔离它无法触发类终止的情况

考虑以下演示代码:

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
Global g_coll1 As Collection
Public Sub Main()
    Dim a As Master
    Set a = New Master
End Sub
现在,对于每次运行,总是调用Servant的类。我在生产代码中看不到任何应该保持集合中的对象被引用的内容

1.)有没有办法强制类在移除时终止?也就是说,我是否可以呼叫Obj.Class_Terminate并确保它每次都能工作

2.)在我的生产代码(和我的小测试应用程序)上,类被标记为“instanceing-5 MultiUse”。我意识到这可能是某种线程问题;是否有一种有效的方法来证明(或反驳)多线程是这个问题的原因——我可能会添加某种类型的跟踪或执行某种类型的测试



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

我们有一个类似的问题,但我们可以将对象的非终止性追溯到应用程序中其他地方的实例

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

Private Sub Class_Terminate()
    Terminate
End Sub

Public Sub Terminate()
    'Do real termination in here'
End Sub
因此,每当您确实希望终止类时(即,当您调用g_coll1.Remove时),您也可以对保留的对象调用
Terminate

我想你也可以公开课堂,但在我看来这有点难看

如果你的观点是(2),我认为这不太可能是线程问题,但我想不出一个好的证明/测试。我想你可以考虑的一个非常重要的问题是:你在应用程序中手动使用线程吗?VB6不会自动执行很多线程。。。(见下文编辑)


[Edit]MarkJ告诉我们,显然构建为ActiveX应用程序意味着VB6会自动执行线程。其他人将不得不探索这一点的含义,因为我不熟悉它

@Ant,我询问多线程的原因是跟踪日志看起来好像我正在执行多个线程。@Ant,Onorio。一个重要的问题是应用程序是否是ActiveX exe?如果是这样,那么VB6将自动为您执行线程处理,“多用途”选项意味着不同的客户端可以共享相同的对象。这可能会引起一些并发症。@MarkJ,答对了。是的,我应该在上面的描述中加上这个。是的,这个应用程序是ActiveX exe。@MarkJ:aha我不知道。有趣。@Onorio:VB6将执行线程处理,如果您使用CreateObject函数从Ax EXE创建实例。操作员New将使用“快捷方式”,并始终在当前线程上创建对象。因此,在您的示例中,线程化不是问题。您可以通过使用hack查看对象的引用计数来检查对象从集合中删除后是否仍被引用:
Private Sub Class_Terminate()
    Terminate
End Sub

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