VB .Net服务在线程休眠时不会停止
我有一个VB .Net服务,它使用System.Threading而不是定时器来基本上做一个定时器应该做的事情。我的问题是在线程处于睡眠状态时停止服务。请参见下面的代码:服务启动VB .Net服务在线程休眠时不会停止
如果例如1分钟后Imports System.Threading
Public Class AService
Private stopping As Boolean
Private stoppedEvent As ManualResetEvent
Public Sub New()
InitializeComponent()
Me.stopping = False
Me.stoppedEvent = New ManualResetEvent(False)
End Sub
Protected Overrides Sub OnStart(ByVal args() As String)
' Add code here to start your service. This method should set things
' in motion so your service can do its work.
End Sub
Protected Overrides Sub OnStop()
' Add code here to perform any tear-down necessary to stop your service.
Me.stopping = True
Me.stoppedEvent.WaitOne()
End Sub
Private Sub ServiceWorkerThread(ByVal state As Object)
' Periodically check if the service is stopping.
Do While Not Me.stopping
' Perform main service function here...
' do anything here and wait 15 minutes before doing it again
Thread.Sleep(15 * 60000) ' Sleep for interval
Loop
' Signal the stopped event.
Me.stoppedEvent.Set()
End Sub
End Class
,就不能停止,直到它每隔15分钟蜱和线程被唤醒。有什么方法可以捕捉服务试图停止的信号,并中断线程?
这是我使用的代码。在睡觉或表演时停止没有问题。
Class MyService
Inherits ServiceBase
Private Shared ReadOnly SleepPeriod As New TimeSpan(0, 15, 0)
Private Shared ReadOnly StopTimeout As New TimeSpan(0, 3, 0)
Private _TerminationHandle As New ManualResetEvent(False)
Private _IsRunning As Boolean = False
Private _ServiceThread As New Thread(Addressof ServiceMain)
Protected Overrides Sub OnStart(args As String())
_TerminationHandle.Reset()
_IsRunning = True
_ServiceThread.Start()
End Sub
Protected Overrides Sub OnStop()
_TerminationHandle.Set()
_IsRunning = False
' Terminate the thread if it doesn't stop within 3 minutes of request.
If Not _ServiceThread.Join(StopTimeout) Then _ServiceThread.Abort()
_TerminationHandle.Close() ' Can use .Dispose() if using .Net 4.0 or later.
End Sub
Private Sub ServiceMain()
Do
' TODO: Do work here. Watch for "_IsRunning = False" to abort working when stopping.
' Sleep for 15 minutes at a time. Terminate when service is stopping.
Loop While _IsRunning AndAlso TerminationHandle.WaitOne(SleepPeriod)
' TODO: Clean up.
End Sub
End Class
在您当前的型号中,没有。您只使用单个线程,并且您的代码在15分钟内显式“暂停”该线程,因此在此期间任何事件都没有响应。但是,如果您对此采取稍微改进的方法,则可以改进:在不同线程中运行您的ServiceWorkerThread
子,然后您的主线程可以保持对外部事件的响应。当“停止”信号到达时,如果需要,您可以强制中止工作线程。
约是怎么回事很好的解释,给这个使用http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx – Gent 2012-02-14 22:18:27
看看在Thread.Interrupt
方法:http://msdn.microsoft.com/en-us/library/system.threading.thread.interrupt.aspx#Y0
然而,这需要你有机会到正在运行的的Thread
实例“的服务。”如果这是主线程,那么这是一个不行,但如果它是一个产生的线程,那么你可以调用中断,它会中断处于休眠/阻塞状态的Thread
。
一试这是主线程 – 2012-02-13 21:26:07
如果您不能将代码移动到单独的线程中,那么除了执行一些反模式忙碌等待外,没有办法绕过它。您可以通过实施类似于rerun的解决方案来最大限度地减少关闭“滞后”,并将睡眠时间设置为更可接受的(几秒钟或更多沿着这些线)。 – Kiril 2012-02-13 21:31:03
由于其保护级别,_TerminationHandle.Dispose()不可访问。有任何想法吗?这是完美的解决方案 – 2012-02-14 15:55:37
我正在使用.Net 3.5,切换到4.0,现在它的工作。我必须做一些测试,但是谢谢,这是一个很好的代码库 – 2012-02-14 16:06:21
啊,我不知道这是最近的一次增加。你可以在早期版本的.Net中使用'.Close()'。我在答案中做了一个笔记。谢谢! – 2012-02-14 21:58:43