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