【发布时间】:2018-03-05 16:55:57
【问题描述】:
我检测到System.Timers.Timer 的奇怪行为:
- 定时器的创建间隔为 1 秒,
AutoReset设置为false。 - 定时器启动,
Elapsed事件在 1 秒内触发。内部事件处理程序timer.Enabled是false,这是预期的,因为AutoReset已设置为false。 - 然后不会触发
Elapsed事件,这是由于计时器停止而预期的。 - 如果现在我们将
timer.AutoReset设置为true,Elapsed事件开始每 1 秒触发一次。timer.Enabled仍然是错误的。
这是Timer 代码中的错误,还是可能有导致这种奇怪行为的原因?
在我的理解中,停止的计时器不应该开始触发事件,即使我们更改了AutoReset 属性。
我知道Elapsed 事件可以在计时器停止后触发,因为执行已经在线程池中排队(问题在这个question 中描述)。但是它没有解释为什么停止的计时器开始触发事件。
这是重现问题的最小示例:
class Program
{
private static System.Timers.Timer timer;
static void Main(string[] args)
{
timer = new System.Timers.Timer
{
AutoReset = false,
Interval = 1000
};
timer.Elapsed += TimerTick;
LogMessage("Starting timer...");
timer.Start();
Thread.Sleep(3000);
LogMessage($"Timer is {(timer.Enabled ? "enabled" : "stopped")}");
LogMessage("Setting AutoReset to true");
timer.AutoReset = true;
Thread.Sleep(Int32.MaxValue);
}
private static void TimerTick(object sender, ElapsedEventArgs e)
{
LogMessage($"Timer Tick: timer.Enabled is {timer.Enabled}");
}
private static void LogMessage(string message)
{
Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff} {message}");
}
}
程序输出:
19:46:23.043 Starting timer...
19:46:24.068 Timer Tick: timer.Enabled is False
19:46:26.053 Timer is stopped
19:46:26.057 Setting AutoReset to true
19:46:27.100 Timer Tick: timer.Enabled is False
19:46:28.103 Timer Tick: timer.Enabled is False
19:46:29.117 Timer Tick: timer.Enabled is False
19:46:30.130 Timer Tick: timer.Enabled is False
19:46:31.144 Timer Tick: timer.Enabled is False
19:46:32.158 Timer Tick: timer.Enabled is False
...
【问题讨论】:
-
这是一个在很多方面都存在严重缺陷的课程。关于这个类是如何发生的,必须有一个很好的战争故事,我猜是一个可用性研究表明没有人能弄清楚如何使用 System.Threading.Timer。但是,是的,这与其代码的编写方式是一致的。你通常总是,总是将 Enabled 属性设置回 true 并且在 Elapsed 中将 AutoReset 翻转为 true 是没有意义的。