终止线程执行24小时

时间:2013-03-20 09:04:44

标签: vb.net multithreading service windows-services

我的服务主要是按照应有的方式运作,但它应该每天只进行一次。

为了安排这个,我的老板建议我睡觉工作线程直到明天早上7点:

这个Thread.Sleep调用直接从他编写的类似服务中复制,显然有效,但这总是抛出ArgumentOutOfRangeException - 返回的值是负数。

    Private Sub startExport()
#If Not Debug Then
            Thread.Sleep(1000 * 60 * 1)
#End If
        While runReportExport
            Try
                runExport()
            Catch ex As Exception
                el.WriteEntry("Error exporting data: {1}")
            Finally
                'sleep thread until tomorrow 7am
                Thread.Sleep(DateTime.Now.Subtract(Date.Today.AddDays(1).AddHours(7)))
            End Try
        End While
    End Sub

我对这一切的运作方式感到很困惑,所以如果有人能为我解释整个时间段的事情,我会非常感激。

另一方面,我的朋友建议我以不同的方式管理线程执行。

以下是他建议我做的事情:

Private lastExecute As DateTime = DateTime.Now

Private Overrides Sub OnStart(ByVal args() As String)
    startService()
End Sub

Private Sub startService()
    Dim nextExecute = lastExecute.AddDays(1)
    If nextExecute >= DateTime.Now Then
        lastExecute = DateTime.Now

        tWorker = New Thread(AddressOf startExport)
        tWorker.IsBackground = True
        tWorker.Start()
    End If
End Sub

他说这将在启动时执行一次工作线程,而不是在另一天执行。虽然这段代码确实可以正常工作,但它并没有阻止服务循环一遍又一遍地执行工作线程(目前它在第一次运行完成后第二次执行)

我个人对这两种方法持开放态度,似乎无法正常工作。

基本上,我在一天结束时所需要的只是每天导出一次数据的服务。

我的老板'Thread.Sleep选项似乎更简单,但我朋友的建议似乎更好的做法。

任何人都可以帮我解决这个问题(此时我并不关心我使用哪一个,只要它有效)?

2 个答案:

答案 0 :(得分:1)

 DateTime.Now.Subtract(Date.Today.AddDays(1).AddHours(7)))

您从当前时间减去未来时间。这总是会产生负值。 KABOOM。

您需要将其反转,从未来时间减去当前时间。为了清晰起见并且避免在DateTime上进行比赛,请说明。现在:

Dim today = DateTime.Now
Dim tomorrow = today.Date.AddDays(1).AddHours(7)
Dim wait = tomorrow - today
Thread.Sleep(wait)

当服务停止时,您需要做一些有用的事情。使用ManualResetEvent做得最好,您将从WaitOne(等待)方法中获得睡眠。顺便说一下,让线程长时间睡眠并且没有做任何有用的事情是非常浪费的。改为使用计时器。

答案 1 :(得分:0)

另一种方法,也就是我使用的方法,每天运行一次特定任务是在计时器中设置任务。在我的情况下,我希望每天早上12:05运行任务。因此,当我的程序启动时,我设置计时器的初始间隔,使得第一个滴答将在第二天的凌晨12:05发生。在此之后,每天一次,在代码结束时执行作为勾选的一部分我再次重置计时器间隔,以便下一个勾号将在第二天上午12:05发生。

...

Timer1.Interval = MillisecondsToMidnight() + 300000 ' next tick 12:05:00 tomorrow

...

Private Function MillisecondsToMidnight() As Integer

    Dim ReturnValue As Integer
    Dim ts As TimeSpan

    Dim Tomorrow As DateTime = Today.AddDays(1)
    ts = Tomorrow.Subtract(Now)

    ReturnValue = ts.TotalMilliseconds()

    ts = Nothing
    Return ReturnValue

End Function