137

There are three Timer classes that I am aware of, System.Threading.Timer, System.Timers.Timer, and System.Windows.Forms.Timer, but none of these have a .Reset() function which would reset the current elapsed time to 0.

Is there a BCL class that has this functionality? Is there a non-hack way of doing it? (I thought perhaps changing the time limit on it might reset it) Thought on how hard it would be to reimplement a Timer class that had this functionality, or how to do it reliably with one of the BCL classes?

3
  • 3
    Using JP's solution use an extension method Commented Jun 25, 2009 at 5:26
  • I too have the same need for reset and for the same reasons mentioned, FileSystemWatcher is unpleasant and inconvenient to use Commented Oct 29, 2009 at 5:52
  • If you use Stopwatch for a timer and go with the extension method answer, be careful because Stopwatch.Restart extension method is coming in .NET 4.0. msdn.microsoft.com/en-us/library/… Commented Nov 30, 2009 at 5:15

11 Answers 11

178

I always do ...

myTimer.Stop(); myTimer.Start(); 

... is that a hack? :)

Per comment, on Threading.Timer, it's the Change method ...

dueTime Type: System.Int32 The amount of time to delay before the invoking the callback method specified when the Timer was constructed, in milliseconds. Specify Timeout.Infinite to prevent the timer from restarting. Specify zero (0) to restart the timer immediately.

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

2 Comments

The other issue is that only woeks with Forms.Timer, and my app has no GUI (Application.Start() with no parameters), so I THINK that the Threading.Timer class is better for other reasons, but good point.
@Matthew: See msdn.microsoft.com/en-us/magazine/cc164015.aspx for a discussion of the various timer classes and when using them is appropriate. In general, though, Forms.Timer should only be used with a GUI. However, besides Forms.Timer and Threading.Timer there is also Timers.Timer.
71

All the timers have the equivalent of Start() and Stop() methods, except System.Threading.Timer.

So an extension method such as...

public static void Reset(this Timer timer) { timer.Stop(); timer.Start(); } 

...is one way to go about it.

3 Comments

I'm not looking to measure elapsed time. My exact usecase for this is that I have a FileSystemWatcher watching a directory and want to catch groups of changes (ie, changes made within for example 5s of each other). The theory being that the first change starts a timer that gets reset with each change till it eventually fires and closes off the group.
Yeah, I spotted that when I re-read your question. Edited my answer.
This works and it is important to note that this won't work if you only call timer.Start(). I made this Linqpad query to test it. Try removing timer.Stop in it and you'll see the difference.
34

For System.Timers.Timer, according to MSDN documentation, http://msdn.microsoft.com/en-us/library/system.timers.timer.enabled.aspx:

If the interval is set after the Timer has started, the count is reset. For example, if you set the interval to 5 seconds and then set the Enabled property to true, the count starts at the time Enabled is set. If you reset the interval to 10 seconds when count is 3 seconds, the Elapsed event is raised for the first time 13 seconds after Enabled was set to true.

So,

 const double TIMEOUT = 5000; // milliseconds aTimer = new System.Timers.Timer(TIMEOUT); aTimer.Start(); // timer start running : : aTimer.Interval = TIMEOUT; // restart the timer 

2 Comments

Problem here is that you don't always know at the moment you wish to reset if the timer is already running or not. So, you would have to do aTimer.Interval = TIMEOUT and a aTimer.Start(). So in the whole, a reset function above uses less lines and variables. Great addition though.
I saw also a problem like that. What I did is : aTimer.Interval = aTimer.Interval. That triggered that the loop was going on. Beats me why but it works...
9

You could write an extension method called Reset(), which

  • calls Stop()-Start() for Timers.Timer and Forms.Timer
  • calls Change for Threading.Timer

Comments

4

For a Timer (System.Windows.Forms.Timer).

The .Stop, then .Start methods worked as a reset.

Comments

4

I just assigned a new value to the timer:

mytimer.Change(10000, 0); // reset to 10 seconds

It works fine for me.

at the top of the code define the timer: System.Threading.Timer myTimer;

if (!active) myTimer = new Timer(new TimerCallback(TimerProc)); myTimer.Change(10000, 0); active = true; private void TimerProc(object state) { // The state object is the Timer object. var t = (Timer)state; t.Dispose(); Console.WriteLine("The timer callback executes."); active = false; // Action to do when timer is back to zero } 

Comments

3

You can do timer.Interval = timer.Interval

Comments

1

I do the following. Disposing the timer and initializing it again. But this will erase any event you attached to this timer.

timer.Dispose(); timer = new System.Timers.Timer(); 

Comments

1

Other alternative way to reset the windows.timer is using the counter, as follows:

int timerCtr = 0; bool timerElapsed = false; Timer mTimer; private void ResetTimer() => timerCtr = 0; private void mTimer_Tick() { timerCtr++; timerElapsed = timerCtr >= 10; if (timerElapsed) { // Perform task } } 

So if you intend to repeat every 1 second, you can set the timer interval at 100ms, and test the counter to 10 cycles.

This is suitable if the timer should wait for some processes those may be ended at the different time span.

3 Comments

Also I don't even know what ctr is. I'm guessing it's counter but even then idk what that is supposed to mean. Is it counting the number of ticks or something?
Yeah, thanks for trying to edit, but the answer appears confusing me and i do not understand at all what @ivan wants to do.
@IARI, I added in some of the missing code. It should make more sense now. A similar idea is to record the start time with DateTime.Now, and then with each tick of the timer, see if the time elapsed from the start time exceeds some time span. To reset, just set the start time to Now.
0

Sorry for arriving late with the answer but it might be helpful. If you need a "watchdog" kind of a timer that will start counting from zero again, use the System.Threading.Timer class and Change method.

Below is a code snippet that will only call test method if there is no interruption from the user for more than 3 seconds:

using System; using System.Threading; namespace WatchdogExample { internal class Watchdog { static void Main(string[] args) { Timer t = new Timer(timer_callback, null, 3000, Timeout.Infinite); while (true) { Console.ReadLine(); t.Change(3000, Timeout.Infinite); } } static void timer_callback(object state) { Console.WriteLine("test"); } } } 

Comments

-1

i do this

//Restart the timer queueTimer.Enabled = true; 

1 Comment

This just enables it. Even if it were disabled beforehand, re-enabling doesn't changed the elapsed time that had been collected to that point.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.