Я думаю, что, возможно, нашел решение и подумал, что поделюсь им, если у кого-то есть идея, как я могу изящно выполнить отключение моего потока.
В моей сборке .NET добавьте еще одно определение события
<InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid(Manager.EventsId)> _
Public Interface IManagerEvents
'Others Removed
<DispId(4)> Sub HostAlive(ByRef alive As Boolean)
End Interface
и в определении кода добавить
Открытый делегат Sub HostAliveDelegate (состояние ByRef As Boolean)
Теперь в основной области кода, потому что мы будем говорить с 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, он всегда связан, поэтому вы не можете просто определить, что нет связанных делегатов событий, и отключиться. Когда вы вызываете событие, если хост-приложение было закрыто, событие не устанавливает для живого значения значение true, и вы можете предположить, что оно было прервано.