tags:

views:

93

answers:

4

I want to trigger KillZombies every night at midnight. The problem I'm having is that the first timer interval is retained and not reset to 86400000 milliseconds as I'm trying to do in my method.

Is there any way to remove the old interval and replace it with a new one?

System.Timers.Timer Timer = new System.Timers.Timer();
Timer.Elapsed += new ElapsedEventHandler(KillZombies);
Timer.Interval = MillisecondsToMidnight;
Timer.Start()

private void KillZombies(object source, ElapsedEventArgs e)
{
//Kill zombies
Timer.Interval = 86400000; //Milliseconds per 24 hours
}
+1  A: 

Try calling Stop() first, then Start()ing it again.

SLaks
After the line: Timer.Interval = 86400000; ?
Soo
`Stop` before, `Start` after.
SLaks
Can you explain what is going on when the timer stops when the interval resets as opposed to keeping the timer running when the interval is reset?
Soo
@SLaks - I thought the same thing as you (obviously, by my answer) but when I looked for an explanation as to why it would work using Reflector I found that both methods should work equally well. Am I missing something obvious?
Justin Niessner
+2  A: 

Hmmmm...seems like a scheduling problem to me.

Why not something a little more tailored to scheduling tasks like Quartz.NET? That way you don't have to worry about setting a Timer to run at midnight and then modifying it later.

If you're truly opposed to a scheduling framework, you could try:

private void KillZombies(object source, ElapsedEventArgs e)
{
    //Kill zombies
    Timer.Stop();
    Timer.Interval = 86400000; //Milliseconds per 24 hours
    Timer.Start();
}
Justin Niessner
For my current project, I need my kill zombies method to just work. There aren't any other scheduled tasks I need to run, so using a framework seems like a bit overkill to get one job done. I could be wrong, but right now, I just need to get this thing to work.I'll keep Quartz in mind for any future projects that require intensive scheduling tasks (which is actually fairly likely).
Soo
A: 

Instead of using such a big interval i would instead use an Interval of maybe one second (or minute) and check DateTime.Now and if it has reached the desired value start the work.

System.Timers.Timer Timer = new System.Timers.Timer();
Timer.Elapsed += new ElapsedEventHandler(KillZombies);
Timer.Interval = 60000;
Timer.Start()

private void KillZombies(object source, ElapsedEventArgs e)
{
    if((DateTime.Now - DateTime.Today) < new TimeSpan(0, 1, 0))
    {
        //ToDo: Kill Zombies
    }
}
Oliver
+4  A: 

FWIW, when using Timers, I always set the AutoReset property to false. This prevents the timer from starting up again, so you have to call Timer.Start() to get it to start counting again. This would avoid the extra calls to Stop()

Also, to be explicit, I would have a function that calculates milliseconds to midnight each time and assign that to the timer's interval every time. Would make your code more clear. And also, if you use Timer.AutoRest = false, the timer won't start counting until you call Timer.Start(), which means if you put the Start() call at the end of your KillZombies method and that method takes 5 seconds to execute, your timer should then be 86400000 - 5000. That 5 second shift would add up over time.

Tim Coker
just wanted to write the same :-)
Stefan Egli
+1 for mentioning accumulation error
Dan Bryant
Accumulation error, never even crossed my mind. I will change the code to recalculate milliseconds to midnight each time. Thanks!
Soo