使用VB6 IDE END Debugging时,Dispose和/或Finalize未调用

时间:2011-06-01 02:01:52

标签: .net com vb6

刚刚提出我的问题。

我已经解决了与此相关的大部分内容。 Detect when a COM Object goes out of Scope

我现在面临一个新问题,而开发人员正在研究VB6代码。如果他们在IDE中运行项目,然后按END,则调用Dispose和Finalize。这就像VB6的Debugging部分只是在不调用disposes等的情况下立即分离。

我已经通过使用标准应用程序关闭测试了这个,并且从COM调用了Finalize - > .NET组件和我的线程关闭,但如果按下End按钮,则没有Finalize,没有Dispose,我的线程一直在运行。

在我的组件中,我尝试了这个

bool debuggerAttachedatStart = System.Diagnostics.Debugger.IsAttached;
System.Windows.Forms.MessageBox.Show("The Debugger is currently -" + debuggerAttachedatStart);

但是当你在VB6中运行它时,它总是为假。

我拿出了Process Explorer并查看了VB6,我注意到它在调试会话启动时创建了一个Event对象,但每次启动它都是一个独特的guid。 (\会话\ 1个\ BaseNamedObjects {70FAF0B5-A76B-4C6A-92BE-5201B2335871})

只是想知道我能做什么,以便我可以优雅地检测到VB6中的调试已经停止(或启动)。

2 个答案:

答案 0 :(得分:3)

不,你无能为力。停止调试不会让程序有机会运行代码。

答案 1 :(得分:0)

我相信我可能找到了一个解决方案并且认为我会分享它,因为有人可以更好地了解我如何能够优雅地执行我的线程的关闭。

在我的.NET程序集中添加另一个事件定义

<InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid(Manager.EventsId)> _
Public Interface IManagerEvents
    'Others Removed
    <DispId(4)> Sub HostAlive(ByRef alive As Boolean)
End Interface

并在代码定义中添加     Public Delegate Sub HostAliveDelegate(ByRef state As Boolean)

现在在Code的主要区域,因为我们将与VB6交谈,我们需要在正确的线程上,所以抓住一个SyncContext。并设置线程。

public sub New()
    Dim operation As ComponentModel.AsyncOperation
    operation = AsyncOperationManager.CreateOperation(Nothing)
    mSync = AsyncOperationManager.SynchronizationContext
    operation.OperationCompleted()
    'setup thread work.....
end sub 

Private Sub ConnectPipe()
    Dim lastAliveCheck As DateTime
    lastAliveCheck = DateTime.Now.AddSeconds(2)
    While Not mRunningEvent.Wait(0)


      'do all the work to prepar and setup the PIPE.
      'if we successfully connect
        Using NoOpTimer As New Threading.Timer(New Threading.TimerCallback(AddressOf TimerTicks), mPipe, 2000, 2000)
            'If we disconnect, this Event gets allowing the exit and reconnect to commence
            mConnectedHold.WaitOne()
        End Using

        'we must have not connected so ensure that we are still inside a running process
            PipeLog.Write("Attempting reconnect to named pipe")
            mConnectedStopper.Wait(500)
            If DateTime.Now > lastAliveCheck Then
                lastAliveCheck = DateTime.Now.AddSeconds(2)
                Dim e As New HostAliveEventArgs()
                OnHostAlive(e)
                If Not e.IsAlive Then
                    'The host did not set the event. Make sure the event is wired up and setting the value to true.
                    Exit While
                End If
            End If
    End While
    DisposePipe
    mExitingEvent.Set()
End Sub       

Protected Sub OnHostAlive(ByVal e As HostAliveEventArgs)
    mSync.Send(AddressOf OnHostAliveContextPost, e)
End Sub

Private Sub OnHostAliveContextPost(ByVal state As Object)
    Dim e As HostAliveEventArgs = CType(state, HostAliveEventArgs)
    RaiseEvent HostAlive(e.IsAlive)
End Sub   

在我们使用该组件的VB6类中。

Private WithEvents comm As IPSClient_Intercommunication.Manager

Private Sub Class_Initialize()
    Set comm = New IPSClient_Intercommunication.Manager
End Sub

Private Sub comm_HostAlive(ByRef alive As Boolean)
    alive = True
End Sub

我发现即使你使用CustomEvent它总是被绑定,所以你不能只确定没有连接的事件委托和断开连接。当主机应用程序关闭时引发事件时,事件不会将alive设置为true,并且您可以认为它已被中止。