C# 定时器过早触发

Posted

技术标签:

【中文标题】C# 定时器过早触发【英文标题】:C# Timer firing too early 【发布时间】: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) 会更易读 【参考方案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时才会被执行...

以上是关于C# 定时器过早触发的主要内容,如果未能解决你的问题,请参考以下文章

计时器每秒触发一次并更新 GUI(C# Windows 窗体)

C# 三个定时器区别

C# 计时器是不是在单独的线程上运行?

C# WinForm 文本框离开焦点事件 问题???

在C#中是否可以在一个列表中添加两个参数?

谁会用asp.net c# 做定时器?就是每天12点定时发邮件,我在网上搜了一下,但没运行成功