1

Is there a way to build a new timer with a given action, but tell it from the start that it must kill itself after one hour? (Can it work it out by itself or do I need another line to handle that?)

Daniel A.A. Pelsmaeker
  • 47,471
  • 20
  • 111
  • 157
user1025852
  • 2,684
  • 11
  • 36
  • 58
  • 3
    Is this WinForms? WPF? Something else? What timer are you using? Can you post some of your code? – Mark Byers Aug 12 '12 at 08:33
  • I have two performance counters. one is updated every second but the other one is updated every hour. So, it's not neat to see at the first hour that part of the counters are zero. Consider that as pure C# 4.0 question - how can I timer an action and make sure to stop it after an hour ? I don't want to start manage it myself... – user1025852 Aug 12 '12 at 08:40

1 Answers1

1

I'd use two timers, one to do whatever you want and the other to kill the first timer after an hour.

Here are two examples, each using a 1 second primary timer that needs to be killed at the fifth second.

If you are using System.Threading.Timer:

Timer actualTimer = new Timer(obj => Console.WriteLine("Timer!"),
    null, 0, 1000);

Timer killingTimer = new Timer(obj =>
{
    Console.WriteLine("Killing timer!");
    // Set the dueTime and timeout to infinite, to stop the timer.
    actualTimer.Change(Timeout.Infinite, Timeout.Infinite);
    killingTimer.Change(Timeout.Infinite, Timeout.Infinite);
}, null, 5000, 5000);

Console.ReadLine();

If you are using System.Timers.Timer:

Timer actualTimer = new Timer();
actualTimer.Interval = 1000;
actualTimer.Elapsed += (sender, e) => Console.WriteLine("Timer!");
actualTimer.Start();

Timer killingTimer = new Timer();
killingTimer.Interval = 5000;
killingTimer.Elapsed += (sender, e) =>
{
    Console.WriteLine("Killing timer!");
    actualTimer.Stop();
    killingTimer.Stop();
};
killingTimer.Start();

All times are in milliseconds (1000 in a second). System.Threading.Timer is preferred according to this post, but System.Timers.Timer is for situations where the timer's methods may be called from different threads, according to this post.

Community
  • 1
  • 1
Daniel A.A. Pelsmaeker
  • 47,471
  • 20
  • 111
  • 157
  • You also want to kill the killingTimer! – usr Aug 12 '12 at 12:00
  • Thank you Virtlink and usr. it works and it is a neat solution (I wish it was in the constructor - but this is also good) – user1025852 Aug 12 '12 at 12:25
  • Another question - should I expect sync issues? for example the killing timer will kill the actual timer in some critical section and exception will be thrown? – user1025852 Aug 12 '12 at 13:38
  • and - I tried to do it as extension method - from some reason the enabled is becoming false - but seems like I cannot set the timer to null from within the extension method... – user1025852 Aug 12 '12 at 14:08
  • 1
    @user1025852 - If you want to use the timer from another thread, [you should use](http://stackoverflow.com/a/1416809/146622) the `System.Timers.Timer`. A timer ensures only that the delegate is called when the timer elapses. Even when you stop the timer while it is currently executing the delegate method, the execution of the will finish completely. So there is no issue with critical sections. – Daniel A.A. Pelsmaeker Aug 12 '12 at 16:03
  • @usr - You are correct, I'll add that when I have a proper text editor nearby. – Daniel A.A. Pelsmaeker Aug 12 '12 at 16:04
  • @Virtlink, probably you also shouldn't set actualTimer to null as the timer callback can be called concurrently. It might race with itself. It would produce a nullref exception. (+1 to your answer, btw) – usr Aug 12 '12 at 16:56
  • @usr - You are correct, but only for the `killingTimer` variable as there is no (captured) reference to the `actualTimer` variable in `actualTimer`'s callback method. – Daniel A.A. Pelsmaeker Aug 12 '12 at 21:20