【问题标题】:C# Timer firing too earlyC# 定时器过早触发
【发布时间】:2019-10-17 10:26:54
【问题描述】:

当我调用方法 random_Start() 时,它首先起作用:第二次控制台打印出现在合理的时间,但随后控制台打印之间的差距越来越小。

在一些打印之后,几乎每次打印都在不到 5 秒的时间内完成,尽管代码应该将 Timer 设置为至少 5 秒,对吧?


        static Timer timer;
        static Random random = new Random();
        public static void random_Start()
        {
            timer = new Timer(random.NextDouble()*10000+5000);
            timer.Elapsed += OnTimedEvent;
            timer.Start();
            Console.WriteLine("Start");
        }

        private static void OnTimedEvent(Object source, ElapsedEventArgs e)
        {
            random_Start();
        }

【问题讨论】:

  • 问题是当您在 OnTimedEvent 委托中调用 random_Start 时,会创建并分配计时器的新实例,它永远不会停止。您不应该在每次计时器经过时都调用 random_Start。
  • random.NextDouble()*10000+5000 似乎很奇怪。为什么不只是random.Next(minValue, maxValue)
  • 确实,为了呼应 rufus 刚才所说的话,如果你想要一个介于 5000 到 15000 毫秒之间的数字,那么调用 random.Next(5000, 15000) 会更易读

标签: c# timer system.timers.timer


【解决方案1】:

设置您的计时器,这样您就不会在每个计时器滴答声中创建一个新实例。在下面的示例中,我禁用了AutoReset,以便我们可以设置新的间隔并再次手动启动计时器。

    static Timer timer;
    static Random random = new Random();
    public static void random_Start()
    {
        timer = new Timer(random.NextDouble()*10000+5000);
        timer.Elapsed += OnTimedEvent;
        timer.AutoReset = false;
        timer.Start();
        Console.WriteLine("Start");
    }

    private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        Console.WriteLine("Tick");
        timer.Interval = random.NextDouble()*10000+5000;
        timer.Start();
    }

【讨论】:

  • 没有必要在Elapsed事件处理程序中调用Start,因为它只会在定时器已经是Enabled时才会被执行...
猜你喜欢
  • 2017-11-01
  • 2014-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-15
  • 2012-06-01
  • 1970-01-01
相关资源
最近更新 更多