刚刚提出我的问题。
我已经解决了与此相关的大部分内容。 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中的调试已经停止(或启动)。
答案 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,并且您可以认为它已被中止。