134

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?

Matthew Scharley
  • 127,823
  • 52
  • 194
  • 222
  • 3
    Using JP's solution use an extension method – benPearce Jun 25 '09 at 05:26
  • I too have the same need for reset and for the same reasons mentioned, FileSystemWatcher is unpleasant and inconvenient to use – John Lewin Oct 29 '09 at 05: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. http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.restart(VS.100,lightweight).aspx – si618 Nov 30 '09 at 05:15

11 Answers11

172

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.

Martin Schneider
  • 14,263
  • 7
  • 55
  • 58
JP Alioto
  • 44,864
  • 6
  • 88
  • 112
  • 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 Scharley Jun 25 '09 at 05:27
  • 3
    @Matthew: See http://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`. – Brian Jun 29 '10 at 19:25
69

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.

Dan
  • 2,338
  • 17
  • 28
  • 2
    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. – Matthew Scharley Jun 25 '09 at 05:35
  • Yeah, I spotted that when I re-read your question. Edited my answer. – Dan Jun 25 '09 at 05:38
  • This works and it is important to note that this won't work if you only call `timer.Start()`. I made [this Linqpad query](https://gist.github.com/jmbeach/de7c9ecc16dd55889e796656c13725b6) to test it. Try removing `timer.Stop` in it and you'll see the difference. – Jared Beach Dec 14 '18 at 14:32
33

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
mMontu
  • 8,983
  • 4
  • 38
  • 53
  • 1
    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. – e-motiv Mar 05 '14 at 17:59
  • 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... – Herman Van Der Blom Apr 18 '19 at 11:28
8

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

  • calls Stop()-Start() for Timers.Timer and Forms.Timer
  • calls Change for Threading.Timer
C_Gehring
  • 7
  • 2
Gishu
  • 134,492
  • 47
  • 225
  • 308
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
}
AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
Quispie
  • 948
  • 16
  • 30
3

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

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

2

You can do timer.Interval = timer.Interval

Ella Sharakanski
  • 2,683
  • 3
  • 27
  • 47
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();
Ravier
  • 41
  • 3
0

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

int timerCtr = 0;
Timer mTimer;

private void ResetTimer() => timerCtr = 0;
private void mTimer_Tick()
{
    timerCtr++;
    // 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.

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
ivan
  • 9
  • 1
  • 1
    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? – AustinWBryan Aug 28 '20 at 08:23
  • 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 Feb 23 '21 at 14:10
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");
        }
    }
}
Ziarek
  • 679
  • 6
  • 14
-1

i do this

//Restart the timer
queueTimer.Enabled = true;
Rissa
  • 191
  • 1
  • 8
  • 1
    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. – vapcguy Aug 30 '17 at 14:57