2009-12-20 63 views
2

我正在写一个启动TCP侦听器的Windows服务。核心代码工作正常,但我在Windows服务的机制方面遇到了一些问题。如何让TCP侦听器服务正确终止?

现在,当我的服务启动时,它创建一个线程并启动线程中的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中,如果该事项。]

回答

7

而不是终止与Thread.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 

当关机()调用socketListen.Close()和辅助线程正在等待新的连接SocketExcpetion将提高。我们忽略了这一点。
在您的OnStop()方法中,您首先通过调用myListener.Shutdown()(然后设置shutingdown标志并关闭套接字),然后等待(达到)某个时间范围(例如,等等),让pmtListener实例有机会正常关闭。一秒)。如果线程仍然处于活动状态,请尝试终止它。

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 
+0

好吧,让我们说pmtListener有一个shutdown()方法。它看起来叫什么?我是否需要重新加入生成的线程? – davidcl 2009-12-20 03:46:45

+1

给我一个或两个例子...我不是一个VB开发人员;-)简短版本:不要使用静态方法(共享子?),但一个pmtListener的实例(dim myListener作为新的pmtListener( )?并在其Main()方法(新线程(AddressOf myListener.Main))上启动线程。 – VolkerK 2009-12-20 03:58:48

+0

该示例似乎有效(仅作为控制台应用程序进行测试,而不是服务)。 Socket.Accept()调用不受ThreadAbortException影响的(非托管)winsock代码。我想知道是否有办法“让它知道”。注意自己:这花了太长时间。练习更多vb.net。它是_is_ dotnet。 – VolkerK 2009-12-20 04:44:56