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

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.


You can use Task Sceduler on windows See daily trigger example for detail.

or use bellow code if you want wrote it yourself:

public void InitTimer()
{
    DateTime time = DateTime.Now;
    int second = time.Second;
    int minute = time.Minute;
    if (second != 0)
    {
        minute = minute > 0 ? minute-- : 59;
    }

    if (minute == 0 && second == 0)
    {
        // DoAction: in this function also set your timer interval to 24 hours
    }
    else
    {
        TimeSpan span = //new daily timespan, previous code was hourly: new TimeSpan(0, 60 - minute, 60 - second);
        timer.Interval = (int) span.TotalMilliseconds - 100; 
        timer.Tick += new EventHandler(timer_Tick);
        timer.Start();
    }
}

void timer_Tick(object sender, EventArgs e)
{
    timer.Interval = ...; // 24 hours
    // DoAction
}

Tags:

C#

.Net

Timer