67326

Timer once a minute on the minute

I can't get the timer to fire once a minute on the minue, 1:00, 1:01, 1:02 etc. Instead, when the timer executes drifts by a couple of seconds each iteration

internal void StartTimer() { DateTime nowEastern = CalendarEntity.Calendar.GetEasternTime(); int secondsInterval = 5; double additionalSeconds = secondsInterval - nowEastern.TimeOfDay.TotalSeconds % secondsInterval; if (additionalSeconds == 0) { additionalSeconds = 1; } var nearestOnOneMinutes = new DateTime( nowEastern.Year, nowEastern.Month, nowEastern.Day, nowEastern.Hour, nowEastern.Minute, nowEastern.Second ).AddSeconds(additionalSeconds); TimeSpan timeToStart = nearestOnOneMinutes.Subtract(nowEastern); TimeSpan tolerance = TimeSpan.FromSeconds(1); if (timeToStart < tolerance) { timeToStart = TimeSpan.Zero; } timer_onem = new System.Threading.Timer(OnTimedEvent, null, (int)timeToStart.TotalMilliseconds, Timeout.Infinite); } private static void OnTimedEvent(object o) { var minute = DateTime.Now.Minute; var second = DateTime.Now.Second; if (minute != lastMinute && second % 60 < 2) { lastMinute = minute; CodeToExecute(); } } static void CodeToExecute() { double tms = 60000; // code here int wait = 60 - System.DateTime.Now.Second; timer_onem.Change(Convert.ToInt64(tms) - wait, Timeout.Infinite); }

<strong>EDIT 1</strong>

I changed the interval so that it fires once a second and then check that the minute has changed. Still drifts

timer_onem = new System.Threading.Timer(OnTimedEvent, null, (int)timeToStart.TotalMilliseconds, 1000); private static void OnTimedEvent(object o) { var minute = DateTime.Now.Minute; if (minute != lastMinute) { lastMinute = minute; CodeToExecute(); } } private static void CodeToExecute() { if (bGenerate) { double tms = 1000; // code timer_onem.Change(Convert.ToInt64(tms), 1000); } }

Answer1:

A Timer is only <strong>guaranteed to be no faster</strong> than Interval.

So you need to call it, say every second and check for the full minute.

For even better precision you would have to check every 1/2 second or better.

It is a basic rule of information theory that says that to measure with a given resolution (1 second in your case) you need to sample with better than twice that resolution. Hence to measure 20kHz you need a smpling rate better than 2x20kHz, say 44.1kHz. (Recognize the numbers?)

If you don't want to call it so <strong>often</strong> for simply getting <strong>one</strong> precise point in time, you could write a little more involved code that on each Tick resets the Timer.Interval to a little <strong>under half</strong> of the remaining time until the next full minute until it is under say 500ms..

There are rather complex things going on in your code wrt to setting up the expected time, though; do make sure they are not the real problem. There should <strong>not</strong> be a <strong>growing</strong> drift from the timer's lack of precision, unless you '<strong>collect</strong>' the errors..

Recommend

  • simple rx code silently fails in windows forms only during debugging in visual studio 2010
  • Get zip code from latitude/longitude
  • Locking an ASP.NET application variable
  • Rx grouped throttling
  • How to pass multiple records to update with one sql statement in Dapper
  • Calculating server uptime gives “The network path was not found”
  • What is the equivalent of Matlab's imadjust in python?
  • Azure service bus paired namespace - simulate failover
  • How to auto update a record in database?
  • NodeJS using node-serialport sometimes becomes unresponsive
  • Determine if a weekday is between two dates in R
  • How can I write a where clause in SQL to filter a DATETIME column by the time of day?
  • Passing variable into xp_cmdshell
  • Year, Month, and Day parameters describe an un-representable DateTime in Persian calender
  • Firestore - Checking The Connection Status Of The Module To The Server
  • Error inflating class ImageButton
  • Filtering SPARQL results by day and month
  • Finding the number of elements less than or equal to k in a multiset
  • Running sp_executesql query expects parameter @statement
  • How to get list of users who's birthday is today in MongoDB
  • dm-script catch error with “Analyze Particles”
  • How can I have an actor running on one process send a message to another actor running on a separate
  • jqPlot date axis - bars drawn on wrong day?
  • MySql - get days remaining
  • How to set a thread specific environment variable in Python?
  • Returning this from a constructor function in JS
  • How to use the resource module to measure the running time of a function?
  • What is the use of a session store?
  • How to get the date of next specified day of week
  • Put value at centre of bins for histogram
  • Validaiting emails with Net.Mail MailAddress
  • Timeout for blocking function call, i.e., how to stop waiting for user input after X seconds?
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • Proper folder structure for lots of source files
  • How does Linux kernel interrupt the application?
  • costura.fody for a dll that references another dll
  • Observable and ngFor in Angular 2
  • UserPrincipal.Current returns apppool on IIS
  • Converting MP3 duration time
  • java string with new operator and a literal