Como posso obter meu serviço de ouvinte TCP encerrar corretamente?
-
20-09-2019 - |
Pergunta
Estou escrevendo um serviço do Windows que inicia um ouvinte TCP. O código principal funciona bem, mas estou tendo vários problemas com a mecânica de um serviço do Windows.
No momento, quando meu serviço é iniciado, ele cria um thread e inicia o ouvinte TCP no thread. Então, quando o serviço para, ele encerra esse tópico:
Public Class txnSocketService
Inherits System.ServiceProcess.ServiceBase
Private listenerThread As Thread
Public Sub New()
Me.ServiceName = "txnSocketService"
Me.CanStop = True
Me.CanPauseAndContinue = True
Me.AutoLog = True
End Sub
Shared Sub Main()
System.ServiceProcess.ServiceBase.Run(New txnSocketService)
End Sub
Protected Overrides Sub OnStart(ByVal args() As String)
listenerThread = New Thread(AddressOf pmtListener.Main)
listenerThread.IsBackground = True
listenerThread.Start()
End Sub
Protected Overrides Sub OnStop()
listenerThread.Abort()
End Sub
Private Sub InitializeComponent()
'
'txnSocketService
'
Me.ServiceName = "txnSocketService"
End Sub
End Class
Iniciar funciona bem. Se eu parar o serviço, no entanto, o processo de serviço não termina. O que estou fazendo errado?
A propósito, atualmente estou fazendo isso no VS2010 Beta 2, se isso importa.
Solução
Em vez de encerrar o thread com thread.abort (), você deve implementar algum método Shutdown () que fecha graciosamente o soquete.
por exemplo
Public Class pmtListener
Protected shutingdown As Boolean = False
' [...] '
Public Sub Shutdown()
shutingdown = True
socketListen.Close()
End Sub
Sub Main()
Dim socketAccepted As Socket
shutingdown = False
socketListen.Listen(3)
While Not shutingdown
Try
socketAccepted = socketListen.Accept()
' do something with socketAccepted '
socketAccepted.Close()
socketAccepted = Nothing
Catch ex As SocketException
If shutingdown Then
' ignoring it '
End If
End Try
End While
End Sub
Quando o Shutdown () chama o SocketListen.Close () e o Thread Worker está atualmente aguardando uma nova conexão, será aumentado o SockeTexCpetion. Nós apenas ignoramos isso.
No seu método ONSTOP (), você primeiro oferece à instância do PMTListener a chance de fechar graciosamente chamando o MyListener.shutdown () (que então define a bandeira de fechamento e fecha o soquete) e depois aguarde (até) uma certa população (por exemplo, um segundo ). Se o tópico ainda estiver vivo, tente encerrá -lo.
Public Class txnSocketService
Inherits System.ServiceProcess.ServiceBase
Protected myListener as pmtListern
Protected listenerThread As Thread
' [...] '
Protected Overrides Sub OnStart(ByVal args() As String)
myListener = new pmtListener
listenerThread = New Thread(AddressOf myListener.Main)
listenerThread.IsBackground = True
listenerThread.Start()
End Sub
Protected Overrides Sub OnStop()
myListener.Shutdown()
listenerThread.Join(1000) ' give it a second '
If listenerThread.IsAlive Then
listenerThread.Abort()
End If
End Sub