Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use the .NET Timer class to trigger an event at a specific time?

Tags:

c#

.net

timer

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.

like image 488
Behrooz Karjoo Avatar asked Dec 25 '10 01:12

Behrooz Karjoo


People also ask

How do I stop a timer elapsed event?

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 tick click elapse count?

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.


2 Answers

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).

like image 153
Dan Tao Avatar answered Oct 12 '22 03:10

Dan Tao


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.

like image 27
VoteCoffee Avatar answered Oct 12 '22 04:10

VoteCoffee