Skip to content

System.Timers.Timer starts when in disabled state after setting interval value #98280

Open
@DoctorMarvin21

Description

@DoctorMarvin21

Description

I've found interesting behavior of System.Timers.Timer when AutoReset = false. Looks like it's there for a while.

When Timer elapsed at least once, it starts automatically when setting any new Interval value even though Enabled is false

Reproduction Steps

const int TimerInterval = 100;
int elapsedTimes = 0;

using var timer = new System.Timers.Timer { AutoReset = false, Interval = TimerInterval };

timer.Elapsed += (s, e) =>
{
    elapsedTimes++;
    Console.WriteLine($"I'm elapsed {elapsedTimes} time(s)");
};

Console.WriteLine($"Starting timer normally");
timer.Start();
Thread.Sleep(TimerInterval * 2);

Console.WriteLine($"Setting timer interval when timer elapsed");
timer.Interval = TimerInterval;
Thread.Sleep(TimerInterval * 2);

Expected behavior

Output of the code snippet is:
Starting timer normally
I'm elapsed 1 time(s)
Setting timer interval when timer elapsed

Actual behavior

Output of the code snippet is:
Starting timer normally
I'm elapsed 1 time(s)
Setting timer interval when timer elapsed
I'm elapsed 2 time(s)

Regression?

I tracked code to the early .NET Framework versions. Looks like it has always been an issue.

Known Workarounds

Use System.Threading.Timer instead of System.Timers.Timer.

Configuration

Tested on .NET 8 and Windows 10.

Other information

There are inconsistent checks for current timer state. Property Enabled setter checks for _enabled field state and if _timer is not null, but Interval property only checks if _timer is not null. ThenMyTimerCallback(object? state) sets _enabled to false without disposing and/or setting _timer to null.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions