If Timer.Enabled is set to true and Timer.AutoReset is set to false, the System.Timers.Timer raises the Timer.Elapsed event only once, the first time the interval elapses.
If Timer.Interval is set after the System.Timers.Timer has started, the count is reset. For example, if you set the interval to 5 seconds and then set Timer.Enabled to true, the count starts at the time Timer.Enabled is set. If you reset the interval to 10 seconds when count is 3 seconds, the Timer.Elapsed event is raised for the first time 13 seconds after Timer.Enabled was set to true.
If the Timer.SynchronizingObject property is null, the Timer.Elapsed event is raised on a System.Threading.ThreadPool thread. If the processing of the Timer.Elapsed event lasts longer than Timer.Interval, the event might be raised again on another System.Threading.ThreadPool thread. In this situation, the event handler should be reentrant.
The event-handling method might run on one thread at the same time that another thread calls the Timer.Stop method or sets the Timer.Enabled property to false. This might result in the Timer.Elapsed event being raised after the timer is stopped. The example code for the Timer.Stop method shows one way to avoid this race condition.
Even if Timer.SynchronizingObject is not null, Timer.Elapsed events can occur after the erload:System.Timers.Timer.Dispose or Timer.Stop method has been called or after the Timer.Enabled property has been set to false, because the signal to raise the Timer.Elapsed event is always queued for execution on a thread pool thread. One way to resolve this race condition is to set a flag that tells the event handler for the Timer.Elapsed event to ignore subsequent events.
The System.Timers.Timer component catches and suppresses all exceptions thrown by event handlers for the Timer.Elapsed event. This behavior is subject to change in future releases of the .NET Framework.