Windows服务:如何在工作线程停止时触发OnStop

时间:2015-05-21 17:54:39

标签: vb.net multithreading service

我在VB.NET中创建了一个Windows服务。 OnStart创建一个工作线程并返回。工作线程启动正常并尝试连接到数据库。如果建立了连接,则线程进入无限循环,这是预期的行为。

Dim _shutdown As Boolean = False 
Private _oPollingThread As Thread

Protected Overrides Sub OnStart(ByVal args() As String)
    _oPollingThread = New Thread(New System.Threading.ThreadStart(AddressOf PollProcess))
    _oPollingThread.Start()
End Sub

如果手动关闭服务(由Windows用户进入“服务”并单击“停止”),OnStop会设置一个布尔值;工作线程看到这一点并成功关闭,OnStop加入,服务停止。一切都好。

Protected Overrides Sub OnStop()
    _shutdown = True

    ' Allow poll process to shut down gracefully (give it up to ten seconds...)
    Dim shutdownCount As Integer = 0

    Do While _oPollingThread.Join(1000) = False And shutdownCount < 10
        shutdownCount = shutdownCount + 1
    Loop

    If _oPollingThread.IsAlive = True Then
        _oPollingThread.Abort()
    End If

End Sub

问题是,如果工作线程没有连接到数据库,如何让服务停止?一旦工作线程终止(而不是进入其无限循环),Windows服务将保持活动状态,并且OnStop不会运行。

1 个答案:

答案 0 :(得分:0)

嗯,我认为Tony Hinkle可能会对事件走上正轨,但我不确定你是否需要BackgroundWorker。你可以声明一个由工作线程引发的WorkerStopped事件吗?然后该服务可以有一个处理它的Sub并停止服务。

它看起来像这样:

Public Class WinService
    '...OnStart(), OnStop()...

    Dim _shutdown As Boolean = False
    Private _oPollingThread As Thread
    Private Event WorkerStopped(sender As Object, e As EventArgs)

    Private Sub PollProcess()
        '...Attempt to connect to db...

        'See if attempt was successful, raise event if not.
        If databaseConnectionFailed Then
            RaiseEvent WorkerStopped(Me, Nothing) 'Could pass back data (error msg?) in EventArgs if desired
        Else
            'Connected to db successfully; proceed
            '...
        End If
    End Sub

    Private Sub StopWork(sender As Object, e As EventArgs) Handles Me.WorkerStopped
        Me.Stop()
    End Sub
End Class

如果您想获得幻想,可以声明自己的自定义WorkerStoppedEventArgs类型并传递该类型而不是香草EventArgs。或者它是自定义的,你可以根本不需要任何参数,但我喜欢在那里遵循惯例。

我希望我可以保证这项工作,但是我写了一个Windows服务已经有6年了,而且我记得他们并不是真的很容易就可以开始尝试!