Why does C# Timer Restarts When I Change Interval in Elapsed function

1.1k Views Asked by At

I am using System.Timers.Timer Class and I want to change it's Interval in the elapsed function. When i set Elapsed property to different value, somehow elapsed function starts firing and firing again althrough timer's Autoreset property is set to false.

my code:

            var timer = new Timer()
            {
                Interval = 1000,
                AutoReset = false,
            };

            timer.Enabled = true;
        
            timer.Elapsed += (sender, eventArgs) =>
            {
                Console.WriteLine("Timer fires");
                timer.Interval = 2000;
            };

The code results in firing timer again and again when i just wanted to change interval for the latter use of the timer.

It would be nice to know why this happens and what should i do to achieve desired behaviour.

2

There are 2 best solutions below

0
AudioBubble On BEST ANSWER

Timer.Close will release all resources attached with this timer object and it seems to help here.

In the Elapsed event handler logic, when the Timer.Interval is set to a number greater than zero, it's telling to invoke the "Elapsed" event again and the whole logic goes into a infinite loop.

static void Main(string[] args)
{
    var timer = new Timer()
    {
        Interval = 1000,
        AutoReset = false,
    };

    timer.Enabled = true;
    timer.Elapsed += (sender, eventArgs) =>
    {
        Console.WriteLine("Timer fires Elapsed = " + timer.Interval.ToString());
        timer.Close();
        timer.Interval = 800;
    };
    Console.WriteLine("The timer event should have fired just once. Press the Enter key to resume ");
    Console.ReadLine();

    // Again enable the timer to make sure it fires the elapsed event after 800 ms
    timer.Enabled = true;
    Console.WriteLine("Press the Enter key to resume ");
    Console.ReadLine();

    // Overwrite the earlier time interval to 200 ms.
    timer.Interval = 200;
    timer.Enabled = true;
    Console.WriteLine("Press the Enter key to resume ");
    Console.ReadLine();
            
    timer.Enabled = true;
    Console.WriteLine("Press the Enter key to exit the program at any time... ");
    Console.ReadLine();
}
2
Wolfram Wisser On

I don't know why the Timer starts again after you change the Interval but here is a Workaround for this problem.

timer.Elapsed += (sender, eventArgs) =>
{
    Console.WriteLine("Timer fires");
    timer = new Timer()
    {
        Interval = 2000,
        AutoReset = false,
    };
};

You could also use the DispatcherTimer instead.

var dt = new DispatcherTimer();

dt.Interval = new TimeSpan(0, 0, 1);

dt.Tick += (sender, eventArgs) =>
{
    dt.Stop();
    dt.Interval = new TimeSpan(0, 0, 2);
};

Edit: After some testing, I have found a better workaround.

If you start the timer again than change the Interval and immediately afterward stop it again then it seems to work.

timer.Elapsed += (sender, eventArgs) =>
{
    Console.WriteLine("Timer fires");
    timer.Enabled = true;
    timer.Interval = 2000;
    timer.Enabled = false;
};