I would like to have an event triggered in my app which runs continuously during the day at a certain time, say at 4:00pm. I thought about running the timer every second and when the time is equal to 4:00pm run the event. That works. But I'm wondering if there's a way to just get the callback once at 4:00pm and not having to keep checking.
It would have already queued before you have called Stop method. It will fire at the elapsed time. To avoid this happening set Timer. AutoReset to false and start the timer back in the elapsed handler if you need one.
Which event occurs each time an interval is elapsed in the timer? Clarification: If the timer is running, its Tick event property occurs each time an interval is elapsed. Every time the Tick event occurs the computer processes the code contained in the Tick event procedure.
How about something like this, using the System.Threading.Timer
class?
var t = new Timer(TimerCallback); // Figure how much time until 4:00 DateTime now = DateTime.Now; DateTime fourOClock = DateTime.Today.AddHours(16.0); // If it's already past 4:00, wait until 4:00 tomorrow if (now > fourOClock) { fourOClock = fourOClock.AddDays(1.0); } int msUntilFour = (int)((fourOClock - now).TotalMilliseconds); // Set the timer to elapse only once, at 4:00. t.Change(msUntilFour, Timeout.Infinite);
Note that if you use a System.Threading.Timer
, the callback specified by TimerCallback
will be executed on a thread pool (non-UI) thread—so if you're planning on doing something with your UI at 4:00, you'll have to marshal the code appropriately (e.g., using Control.Invoke
in a Windows Forms app, or Dispatcher.Invoke
in a WPF app).
Starting with .NET 4.5 there's a really clean solution:
public async void ScheduleAction(Action action, DateTime ExecutionTime) { await Task.Delay((int)ExecutionTime.Subtract(DateTime.Now).TotalMilliseconds); action(); }
Here's a solution without async/await:
public void Execute(Action action, DateTime ExecutionTime) { Task WaitTask = Task.Delay((int)ExecutionTime.Subtract(DateTime.Now).TotalMilliseconds); WaitTask.ContinueWith(_ => action); WaitTask.Start(); }
It should be noted that this only works for about 24 days out because of int32 max value, which is plenty for your case, but worth noting.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With