如何让我的TCP侦听器服务正确终止?

dav*_*dcl 2 .net vb.net windows-services visual-studio-2010-beta-2

我正在编写一个启动TCP侦听器的Windows服务.核心代码工作正常,但我在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
Run Code Online (Sandbox Code Playgroud)

启动工作正常.但是,如果我停止服务,则服务进程不会终止.我究竟做错了什么?

[顺便说一句,我现在正在VS2010 Beta 2上这样做,如果这很重要的话.]

Vol*_*erK 7

您应该实现一些正常关闭套接字的shutdown()方法,而不是使用Thread.Abort()终止线程.

例如

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
Run Code Online (Sandbox Code Playgroud)

当Shutdown()调用socketListen.Close()并且工作线程当前正在等待新连接时,将引发SocketExcpetion.我们忽略这一点.
在你的OnStop()方法中,你首先给pmtListener实例一个机会,通过调用myListener.Shutdown()然后设置shutingdown标志并关闭套接字来优雅地关闭然后等待(直到)某个时间跨度(例如一秒) ).如果线程仍处于活动状态,请尝试终止它.

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
Run Code Online (Sandbox Code Playgroud)