在服务中的每个指定时间运行方法而不重复

时间:2015-01-14 07:32:29

标签: vb.net timer synchronization

我有一个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得到两个输入?我认为计时器事件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

1 个答案:

答案 0 :(得分:1)

显示的时间被截断,定时器并不是那么精确(分辨率有时会在几十毫秒内测量,更不用说多任务处理可能带来的延迟)。因此,它可能只是一个定时器事件触发两次,几乎相隔一秒,但在同一显示秒内的情况。

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

如果您想检查系统的分辨率,您必须深入研究Interval文档中给出的示例。

我建议您专门跟踪当天是否已达到指定时间,如果还没有,请允许该事件通过。显然,为了以防万一,可以使用SynchronizingObject上的Timer来同步对此的访问。