1

I want to wait for x hours before executing some code in C#. i thought using a timer would be a good idea. (using thread.sleep does not seem right). But it just does not work. i am using the following code:

static void Main(string[] args)
{
    System.Timers.Timer timer = new System.Timers.Timer();
    timer.Interval = x * 3600000;
    timer.Enabled = true;
    timer.Elapsed += (o, e) => SomeFunction(username);
    timer.AutoReset = true;
    timer.Start();
}

this code supposed to wait for x hours and then execute SomeFunction but when i debug it, the main function ends after timer.start().

do you see any problem here? or can you suggest an alternative besides thread.sleep or await Task.Delay() ?

8
  • System.Timers.Timer normally uses a background thread to raise the event, so it will start the timer and then move on, it does not block. Commented Jun 17, 2015 at 8:46
  • Yes I see a problem there. The call to timer.Start() is asynchronously. This means after the call of timer.Start() execution will continue. This ends your program instantly. What you could do is the most obvious solution to send your main in a endless loop after calling timer.Start() Commented Jun 17, 2015 at 8:46
  • What does "does not work" mean? (Also, i'm curious, is this the value you've used for testing or did you try with a lower interval?) Commented Jun 17, 2015 at 8:47
  • 1
    Of course Main exits - there's no code in it after timer.Start();. So if your application has nothing else to do, Thread.Sleep isn't really any worse than using a timer. That said, it's still a bad idea to use a timer (or Thread.Sleep) for this. Why not use e.g. windows task scheduler instead? What are you actually trying to do? Why do you want to run an application that only does something hours after it's launched? Commented Jun 17, 2015 at 8:47
  • You don't even need a timer for this, record start time, enter an unbound loop and then periodically check time difference and sleep. Commented Jun 17, 2015 at 8:48

3 Answers 3

2

As soon as your Main function exits, your process ends, along with any background threads including timers.

You need to keep your main thread alive using Thread.Sleep(), Console.ReadKey() or whatever seems appropriate.

Alternatively, if you don't want to keep your process alive, you can register a scheduled task with Windows to be run in an hour's time, and then end.

Sign up to request clarification or add additional context in comments.

Comments

1

There are two problems here. The first is that an executable will exit when all foreground threads are finished running. The only foreground thread is that going through Main() so it will then exit.

The second is that you aren't storing timer anywhere. Even if another thread was keeping the executable going, timer is eligible for garbage collection perhaps as soon as timer.Start() returns and certainly after Main() exits.

using thread.sleep does not seem right

It generally isn't a good idea, but considering that you only have one thread anyway, and considering that you have to have at least one foreground thread in an application, Thread.Sleep seems perfectly reasonable in this particular case. Task.Delay just as much.

More generally, I think I would prefer this to be either a scheduled task or a service. In particular, in cases where I want to wait hours before something is done, I very often want this to survive reboots.

2 Comments

Not sure about this: timer is eligible for garbage collection I thought it would live while it is running. Good thinking about wanting to survive reboots with a service!
@TaW it most certainly is. TImers are a very common use for GC.KeepAlive() for precisely this reason. (Note that GC.KeepAlive() does nothing except be a method that accepts an object as a parameter and which can't be inlined, which suffices to prevent collection because the compiler can't reuse the stack space until after it's called KeepAlive()).
0

Check out Quartz.Net and this for scheduled tasks.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.