Как я могу заставить службу прослушивателя TCP завершиться правильно?
Я пишу службу Windows, которая запускает прослушиватель TCP. Основной код работает нормально, но у меня есть несколько проблем с механикой службы Windows.
Прямо сейчас, когда моя служба запускается, она создает поток и запускает прослушиватель TCP в потоке. Затем, когда служба останавливается, она завершает этот поток:
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
Запуск работает нормально. Однако если я остановлю службу,процесс службы не завершится. Что я делаю не так?
[по кстати, я сейчас делаю это на VS2010 Beta 2, если это имеет значение.]
1 ответ:
Вместо того, чтобы заканчивать поток с потоком.Abort() вы должны реализовать некоторый метод shutdown (), который изящно закрывает сокет.
Например
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
Когда Shutdown () вызывает socketListen.Close () и рабочий поток в данный момент ожидает нового соединения, которое вызовет SocketExcpetion. Мы просто игнорируем это.
В своем методе OnStop () вы сначала даете экземпляру pmtListener шанс завершить работу изящно, вызвав myListener.Shutdown () (который затем устанавливает флаг выключения и закрывает сокет), а затем ждать (до) определенного промежутка времени (например, одну секунду). Если нить все еще жива, попробуйте прервать ее.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