问题
I'm writing a Windows service which starts a TCP listener. The core code works fine, but I'm having several problems with the mechanics of a Windows service.
Right now, when my service starts up, it creates a thread and starts the TCP listener in the thread. Then, when the service stops, it terminates that thread:
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
Starting up works fine. If I stop the service, however, the service process doesn't terminate. What am I doing wrong?
[By the way, I'm currently doing this on VS2010 Beta 2, if that matters.]
回答1:
Instead of terminating the thread with Thread.Abort() you should implement some shutdown() method that gracefully closes the socket.
e.g.
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
When Shutdown() calls socketListen.Close() and the worker thread is currently waiting for a new connection a SocketExcpetion will be raised. We just ignore that.
In your OnStop() method you first give the pmtListener instance a chance to shutdown gracefully by calling myListener.Shutdown() (which then sets the shutingdown flag and closes the socket) and then wait (up to) a certain timespan (e.g. one second). Should the thread still be alive try to terminate it.
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
来源:https://stackoverflow.com/questions/1934746/how-can-i-get-my-tcp-listener-service-to-terminate-correctly