运行 方法在服务内每隔指定时间不重复

Run method every specified time within a service without repeating

我有一个 Windows 服务,如下所示:

Protected Overrides Sub OnStart(ByVal args() As String)
    Dim timer As System.Timers.Timer = New System.Timers.Timer()
    timer.Interval = 1000       '1 sec
    AddHandler timer.Elapsed, AddressOf Me.OnTimer
    timer.Start()
End Sub

Private Sub OnTimer(sender As Object, e As Timers.ElapsedEventArgs)
    Dim Time As String = DateTime.Now.ToString("hh:mm:ss tt")
    If Time = "01:58:15 PM" Or Time = "02:42:15 PM" Or Time = "02:43:15 PM" _
            Or Time = "03:44:15 PM" Or Time = "06:00:15 PM" _
            Or Time = "12:00:15 AM" Or Time = "05:00:15 AM" Then
        Dim path As String = Application.StartupPath & "\test.log"
        Dim strFile As String = String.Format(path, _
                DateTime.Today.ToString("dd-MMM-yyyy"))
        File.AppendAllText(strFile, String.Format("Message at-- {0}{1}", _
                DateTime.Now, Environment.NewLine))
    End If
End Sub

你能给我解释一下为什么 3:44:15 PM 有两个输入吗?我认为计时器事件 OnTimer 会暂停,直到之前的 OnTimer 作业完成,然后时间会有所不同,并且不会在同一时间内进入。怎么了?

Message at-- 1/13/2015 3:44:15 PM
Message at-- 1/13/2015 3:44:15 PM
Message at-- 1/14/2015 12:00:15 AM
Message at-- 1/14/2015 5:00:15 AM

进一步讨论:

Private Sub OnTimer(sender As Object, e As Timers.ElapsedEventArgs)
    RemoveHandler timer.Elapsed, AddressOf Me.OnTimer
    Dim Time As String = DateTime.Now.ToString("hh:mm:ss tt")
    If Time = "01:58:15 PM" Or Time = "02:42:15 PM" Or Time = "02:43:15 PM" _
            Or Time = "03:44:15 PM" Or Time = "06:00:15 PM" _
            Or Time = "12:00:15 AM" Or Time = "05:00:15 AM" Then
        Dim path As String = Application.StartupPath & "\test.log"
        Dim strFile As String = String.Format(path, _
                DateTime.Today.ToString("dd-MMM-yyyy"))
        File.AppendAllText(strFile, String.Format("Message at-- {0}{1}", _
                DateTime.Now, Environment.NewLine))
    End If
    AddHandler timer.Elapsed, AddressOf Me.OnTimer
End Sub

显示的时间是 t运行 时间,计时器并不是那么精确(分辨率有时以几十毫秒为单位,更不用说多任务处理可能带来的延迟)。因此,这可能只是计时器事件触发两次的情况,相隔几乎一秒,但在显示的同一秒内。

此外,根本无法保证前面的事件处理程序将完成其工作,除非事件是在同一线程上触发的。也就是说,用旧 DoEvents 之类的东西不小心允许重入事件并不难。而且,事实上,class 甚至被设计为 运行 多线程,可能会在线程池线程上触发事件,即或多或少会随意,除非提供 SynchronizingObject。 (事实并非如此。)

如果您想检查系统的分辨率,则必须深入研究 Interval.

文档中给出的示例

我建议您专门跟踪当天的活动是否已到指定时间,如果未到,则让活动继续进行。显然,同步访问以防万一,可能在 Timer.

上使用 SynchronizingObject