Timing Challenge - (every hour on the hour)

I’m looking for some suggestions on an approach to achieve the result that an event will be enabled to fire every hour on the hour. The existing application has a timer that fires every 10 seconds to run a thread that checks and updates a number of processes so long as the thread is not currently running. What I would like to do is set a Boolean variable that will initiate one of the thread’s run tasks to fire only when the value is true. What I’m struggling with is how to insure the the value gets set as true every hour on the hour regardless of what time of day the application was started or last paused.

Thoughts? Suggestions?

timers are not accurate (as they can be slowed down by other system processes)
What I have do in the past is to set a single timer and vary its period.
each time it fired I check the actual clock… and depending on how far from the hour it was, I would shorten the period

  • Check every 55 minutes
  • adjust the period to 1/2 the remaining time
  • check the real clock
  • if clock >= hour then fire event… goto step 1
  • goto step 2

technincaly this should not miss the mark by more that 1 second… but 100% accuracy is near impossible

Implementation depends on how close to the hour you want it. If you want it bang on the hour to the ms then you will need to calculate it (or use a 1ms timer), if you dont mind it being off by up to a second just use a second timer (<=1000) and check if its past 00:00 then set a bool so it knows that its fired that hour.

Thanks Dave. That’s a decent approach. I’m not looking for absolute accuracy. I really want the task to execute predictably so that if users provide input by a certain time then they know it will get queued up for processing by a certain time. What you suggest should work.

If anyone else has an alternate approach I might consider fire away

So based on Dave’d and Julian’s suggestions/comments, here is what I will be trying. If you have criticism for something I’ve missed or suggestions to improve it I’m open to your feedback.

Function that calculates the total second of the next hour on the hour

Public Function GetNextHourTotalSeconds() as Double dim d As Date = New Date d.Hour = d.Hour + 1 d.Minute = 0 d.Second = 0 Return d.TotalSeconds End Function

Function that calculates the period to set the timer for the next hour on the hour action Event to Trigger

Public Function GetNextBatchPeriodMilliseconds() as Integer Dim d As Date = New Date Dim nextmilliseconds As Integer nextmilliseconds = (GetNextHourTotalSeconds - d.TotalSeconds) * 1000 Return nextmilliseconds End Function

In the App.Open Even I call a Method called ProcessingStart() Among other things it creates two new timer objects, BatchPeriodTask and PollPeriodTask. BatchPeriodTask sets the Boolean variable BatchRun to True every hour so long as it is already False. PollPeriodTask executes a thread every 10 seconds so long as it is not already running

[code]Public Sub ProcessingStart()
BatchPeriodTask = New BatchPeriodTimer
BatchNextHourTotalSeconds = GetNextHourTotalSeconds
BatchPeriodTask.Period = GetNextBatchPeriodMilliseconds
BatchPeriodTask.Mode = 2

PollPeriodTask = New PollPeriodTimer
PollPeriodTask.Period = DBPollingFrequency
PollPeriodTask.Mode = 2
AppPaused = False
LogTransactions(“Started processing queued jobs”)
End Sub[/code]

Timer BatchPeriodTask Action Event sets the Boolean variable BatchRun to True every hour so long as it is already False. If the timer fires before the the current total seconds is greater than or equal to the variable BatchNextHourTotalSeconds then it sets the period to wait 10 more seconds

Sub Action() Handles Action Dim d As Date = New Date If d.TotalSeconds >= BatchNextHourTotalSeconds If BatchRun = False BatchRun = True End If BatchNextHourTotalSeconds = GetNextHourTotalSeconds Me.Period = GetNextBatchPeriodMilliseconds Else Me.Period = 10000 End If End Sub

Finally in the Thread that runs every 10 seconds which the Run Event checks for a number of status changes in a database and also checks various Boolean variables, and processes changes when they have occurred, I look for the value of the variable BatchRun to be True and if so do some Batch stuff.

Sub Run() Handles Run Dim b As Boolean Dim sqlString,desc,err As String MyAppThreadTaskRunning = True b = DBConnect(MySQLDBName) If b = True Then //---------------------------------------------------------------------------------------- // Do some stuff //---------------------------------------------------------------------------------------- If BatchRun = True // Do the batch Processing stuff BatchRun = False End If //---------------------------------------------------------------------------------------- DBClose Else desc = "MyAppThreadTThread.DBConnect.Error" err = ": " + "The MyAppThread Returned a DB connection Error" // Log the Exception LogExceptions(desc+err) // Send a Notification Email SendEmail(desc + err + " - Processing Jobs was aborted." ,"MyAppThread." + desc,"text") End If MyAppThreadTaskRunning = False End Sub

Thanks for the help guys.