0

我的服务大部分都在正常工作,但它应该每天只工作一次。

为了安排这个,我的老板建议我让工作线程睡到明天早上 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 选项似乎更简单,但我朋友的建议似乎是更好的做法。

谁能帮我解决这个问题(此时我不在乎我使用哪一个,只要它有效)?

4

2 回答 2

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

您从当前时间中减去未来时间。这总是产生负值。卡布姆。

您需要将其反转,从未来时间中减去当前时间。为清晰起见并避免在 DateTime.Now 上进行比赛:

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

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

于 2013-03-20T11:22:19.873 回答
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
于 2013-03-20T11:10:56.413 回答