VB6集合删除不会激发Class_Terminate [英] VB6 Collection Remove Doesn't Fire Class_Terminate

查看:336
本文介绍了VB6集合删除不会激发Class_Terminate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我提前道歉;这是一个长期的问题。我已尽量简化尽可能多的,但它仍然是一个更长的风,比我所看到的。

I apologize in advance; this is a long question. I've tried to simplify as much as I can but it's still a bit more long-winded than I'd care to see.

在某些旧代码中, ve得到了VB6集合。此集合通过.Add方法添加对象,并通过.Remove方法删除它们。然而,通过跟踪我可以看到,有时当.Remove被调用时,似乎类的终止对象不被调用。但它不一致;它只发生很少,我不能孤立的情况下,它不能启动类终止。

In some legacy code, we've got a VB6 collection. This collection adds objects via the .Add method and removes them via the .Remove method. However, via tracing I can see that sometimes when the .Remove is called it appears that the class terminate for the object isn't called. But it's not consistent; it happens only rarely and I can't isolate the circumstances under which it fails to fire the class 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
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

这是测试用具代码: / p>

and this is the test harness code:

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

总是调用Servant的class_terminate。我在生产代码中看不到任何东西,应该保持引用集合中的对象。

Now, for every run, the class_terminate of Servant is always invoked. And I can't see anything in the production code which should keep the object in the collection referenced.

1。)有没有办法强制类在Remove中终止?也就是说,我可以调用Obj.Class_Terminate,并放心它会工作吗?

1.) Is there any way to force the class terminate on the Remove? That is, can I call Obj.Class_Terminate and be assured it will work every time?

2。)在我的生产代码(和我的小测试应用程序)标记为Instancing - 5 MultiUse。我意识到这可能是某种形式的线程问题;是否有一个有效的方法来证明(或反驳)多线程是这个问题的原因 - 我可能添加一些类型的跟踪或可能执行的其他类型的测试?

2.) On my production code (and my little test app) the classes are marked "Instancing - 5 MultiUse". I realize this may be some sort of threading issue; is there an effective way to prove (or disprove) that multi-threading is the cause of this issue--some sort of tracing I might add or some other sort of test I might perform?

编辑:在下面的每个MarkJ的洞察性的评论,我应该补充说,上面的测试和生产代码都是ActiveX exe's的一部分原因,我问关于mulit线程。

Per MarkJ's insightful comment below, I should add that the test posted above and the production code are both ActiveX exe's--part of the reason I ask about mulit-threading.

推荐答案

我们有一个类似的问题,但是我们可以跟踪对象的未终止

We had a similar issue, but where we could trace the non-termination of the objects to be down to an instance being held elsewhere in our application.

最后,我们必须这样写我们的Termination方法:

In the end, we had to write our Termination method like this:

Private Sub Class_Terminate()
    Terminate
End Sub

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

所以,只要你真的想要类被终止你调用g_coll1.Remove),你还可以在持有的对象上调用 Terminate

So whenever you really wanted the class to be terminated (i.e. when you call g_coll1.Remove), you can also call Terminate on the held object.

也让Class_Terminate公开,但是这在我看来有点丑。

I think that you could also make Class_Terminate public, but that's a bit ugly in my opinion.

重点你的观点(2),我认为这是不太可能是一个线程问题,但我可以不要想到一个好的证明/测试从我的头顶。我想你可以考虑的一个非常完美的事情是:你手动使用线程在你的应用程序中? VB6不会自动执行大量线程...(见下面的编辑)

Re your point (2), I think it's very unlikely to be a threading issue, but I can't think of a good proof/test off the top of my head. I suppose one very quite thing you can consider is: do you manually use threading in your application? VB6 doesn't do much threading automatically... (see edit below)

[编辑] MarkJ告诉我们,应用程序意味着VB6 自动执行线程。有人会不得不去探索这个的含义,因为我不熟悉它!

[Edit] MarkJ tells us that apparently building as an ActiveX application means that VB6 does automatically do threading. Someone else will have to explore the implications of this, since I wasn't familiar with it!

这篇关于VB6集合删除不会激发Class_Terminate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆