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.

Foi útil?

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top