HOWTO · Csharp
How to Reset Timer in C#
Restart a one-shot System.Timers.Timer in C# with Stop and Start, and learn how AutoReset controls recurring elapsed events.
On this page
To reset a timer interval in C#, call Stop() and then Start() on a System.Timers.Timer. The type has no Reset() method. Set AutoReset according to whether you want one elapsed event or repeated events; that property does not restart a running countdown on demand.
Which C# timer behavior do you need?
Choose a one-shot timer when an operation should happen once after a delay, or when your code will explicitly schedule the next interval. Set AutoReset to false, then use Stop() and Start() whenever you need a fresh interval. For periodic work, set AutoReset to true and let the timer raise Elapsed after each interval.
If a timer is already running and you need to postpone its next event, stop and start it. Starting an already-enabled timer does not provide a separate reset operation. Configure the interval in milliseconds, and use a positive duration that suits the work; a timer is for scheduling callbacks, not for measuring precise elapsed time.
How System.Timers.Timer handles elapsed events
System.Timers.Timer raises its Elapsed event after the configured Interval. Enabled indicates whether the timer is running; Start() enables it and Stop() disables it. The event handler receives an ElapsedEventArgs value, which includes the signal time. Handlers run asynchronously, so they can overlap when recurring work takes longer than the interval. Keep shared state safe and avoid assuming the callback runs on the UI thread.
AutoReset is a Boolean property. With true, the timer schedules subsequent elapsed events at the interval. With false, it raises one event and then stops. It controls repetition, not a command to restart the current countdown. For a one-shot timer that needs another interval, explicitly call Start() again after handling the event.
Restart a one-shot timer with Stop and Start
For a running one-shot timer, call Stop() to cancel its pending schedule, then call Start() to begin a new interval. This is the practical reset pattern. If the timer has already raised its event with AutoReset set to false, call Start() to schedule another one. Set AutoReset before starting when you want its behavior to be clear from the beginning.
Remember that timer callbacks are asynchronous. A callback may already be queued when another part of the program stops the timer, so coordinate shutdown and shared data when that distinction matters. Keep the handler short, or move lengthy work to a controlled worker so recurring ticks do not compete with unfinished work.
Use AutoReset for recurring intervals
Set AutoReset = true for a recurring interval, such as polling or periodically refreshing a value. Each elapsed event is scheduled according to the timer interval. Set it to false when you need one event and will decide explicitly when to start the next interval. Neither setting exposes a countdown value or changes the interval of an already scheduled tick in place; stop and start to schedule a fresh interval.
Do not use a recurring timer as a precise clock. Scheduling can be delayed by thread-pool load, and the callback may not begin exactly at the requested millisecond. If each operation must finish before the next begins, use one-shot scheduling after the operation completes, or add synchronization around the work.
Stop and dispose the timer safely
Call Stop() when the timer should no longer schedule events. When the owning operation is finished, call Dispose() to release the timer’s resources. Stopping and disposing solve different problems: Stop() ends active scheduling, while Dispose() ends the timer’s lifetime. Do not restart a disposed timer; create a new instance if another operation needs a timer.
Because Elapsed runs asynchronously, stopping a timer does not make an already-running handler disappear. If shutdown must wait for a callback, coordinate with that handler using a synchronization mechanism appropriate to the application. Keep the timer alive for as long as its handler may use it, and unsubscribe handlers when a longer-lived timer no longer needs them.
Complete example: restart a one-shot timer
This complete example raises one event after two seconds, starts a fresh interval from that handler, and then exits after the second event. AutoReset = false makes each event a one-shot; Stop() and Start() schedule the second interval explicitly. The completion signal lets Main wait for both callbacks before cleanup.
Run this example:
using System;
using System.Threading;
using System.Timers;
class TimerRestartExample
{
static void Main()
{
using (var completed = new ManualResetEventSlim())
using (var timer = new System.Timers.Timer(2000))
{
int eventCount = 0;
timer.AutoReset = false;
timer.Elapsed += (sender, args) =>
{
eventCount++;
Console.WriteLine("Elapsed event " + eventCount);
if (eventCount == 1)
{
timer.Stop();
timer.Start();
}
else
{
completed.Set();
}
};
timer.Start();
completed.Wait();
timer.Stop();
}
}
}
Elapsed event 1
Elapsed event 2
The supplied runtime run completed successfully and printed both elapsed events shown above. In an application, choose an interval and completion strategy that fit its lifetime; a service or UI may keep running after a timer event rather than wait and exit as this demonstration does.