我的服务主要是按照应有的方式运作,但它应该每天只进行一次。
为了安排这个,我的老板建议我睡觉工作线程直到明天早上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选项似乎更简单,但我朋友的建议似乎更好的做法。
任何人都可以帮我解决这个问题(此时我并不关心我使用哪一个,只要它有效)?
答案 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