Reputation: 61
I'm running into an issue where the Elapsed event is triggered prior to the interval. I have the interval set for say.. 10000ms and the event will get triggered at roughly 4500ms. I know that this specific timer is not too precise but I do know for sure that it is far more precise than what it is showing.
I have checked to make sure that there is not more than one timer calling this event as well. This solution works perfectly on two out of the three windows machines that it is installed on.
Could it be a problem with the .net version, clr version, etc.
I know that there are other ways of accomplishing this but I am just looking for suggestions on what could be causing this to work on only 2 out of 3 servers.
Below I am creating the timer only once at startup of the service..
checkTimer = new System.Timers.Timer(getSecondsLeft());
checkTimer.Elapsed += checkNowEvent;
checkTimer.AutoReset = true;
checkTimer.Enabled = true;
Here is the method that is used to calculate the number of milliseconds until the next minute
private double getSecondsLeft()
{
DateTime now = DateTime.Now;
// Has a chance to trigger a few milliseconds before new minute. Added 50ms to interval
return ((60 - now.Second) * 1000 - now.Millisecond) + 50;
}
And finally the elapsed time event.
private void checkNowEvent(object sender, ElapsedEventArgs e)
{
try
{
// Stop timer to keep from firing this event again
checkTimer.Enabled = false;
// DOING WORK HERE
}
finally
{
// Set the interval as to tick on the start of the next minute
checkTimer.Interval = getSecondsLeft();
// Start timer again
checkTimer.Enabled = true;
}
}
I just did some more testing with this and I added some stopwatch functionality to see if the interval was actually firing when it is supposed to and it looks like it is. However, when i calculate the correct number of milliseconds to the next minute BUT it is acting as if this implementation of Timer is running faster than the system clock... If that makes any sense.
Here is the code i used to find that out.
private void checkNowEvent(object sender, ElapsedEventArgs e)
{
stopWatch.Stop();
_Log.LogDebug(stopWatch.Elapsed.ToString());
try
{
// Stop timer to keep from firing this event again
checkTimer.Enabled = false;
// DOING WORK HERE
}
catch (Exception ex)
{
// CATCHING EXCEPTIONS HERE IF ANY
}
finally
{
// Set the interval as to tick on the start of the next minute
checkTimer.Interval = getSecondsLeft();
_Log.LogDebug(checkTimer.Interval.ToString());
// Start timer again
checkTimer.Enabled = true;
stopWatch.Reset();
stopWatch.Start();
}
}
Upvotes: 4
Views: 1876
Reputation: 61
The reason that it is firing before the new minute is due to the fact that there is a problem with the system time. DateTime.Now returns the correct number of milliseconds until the next minute but the system time is moving very slow. The timer implementation seems to be working correctly as I verified with the stopwatch. I just synced the system time with the other two working pcs and not but 5 minutes later it is a couple minutes slow again.
Upvotes: 2