Windows服务:工作线程停止时如何触发OnStop
Windows Service: How to trigger OnStop when the worker thread stops
我在 VB.NET 中创建了一个 Windows 服务。 OnStart 创建一个工作线程和 returns。工作线程启动正常并尝试连接到数据库。如果建立连接,线程将进入无限循环,这是预期的行为。
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 不会 运行。
嗯,我认为 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 年了,而且我记得它们并不容易启动并尝试!
我在 VB.NET 中创建了一个 Windows 服务。 OnStart 创建一个工作线程和 returns。工作线程启动正常并尝试连接到数据库。如果建立连接,线程将进入无限循环,这是预期的行为。
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 不会 运行。
嗯,我认为 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 年了,而且我记得它们并不容易启动并尝试!