首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在特定时间、特定时间启动定时器?

如何在特定时间、特定时间启动定时器?
EN

Stack Overflow用户
提问于 2016-06-06 19:50:47
回答 2查看 15K关注 0票数 5

以下是场景:

有一个Textbox,用户在其中输入DispatcherTimer必须开始的时间。定时器设置为始终运行4小时,Timer.Tick事件播放声音。假设计时器在04:00:00 (HH:mm:ss)开始,它应该运行到8:00:00,然后停止。然后,当用户将时间更改为09:00:00时。计时器应该运行到13:00:00,以此类推。

如何才能做到这一点?我不能运行1分钟的计时器来检查正确的时间,因为这会对系统造成很大的负担。

感谢所有的帮助。提前谢谢你。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-06 20:23:04

下面的方法根据提供的日期时间(即输入到文本框中的时间)启动一个初始计时器。当时间到达时,它启动一个二级计时器,从那时起每四个小时触发一次。

我使用的是System.Timers定时器而不是Sytem.Threading定时器(因为具有讽刺意味的是system.threading定时器不是线程安全的!)

代码语言:javascript
复制
    public void StartTimer(DateTime time)
    {
        const int fourHoursInMilliseconds = 4 * 3600 * 1000;

        var fourHourTimer = new Timer() {Interval = fourHoursInMilliseconds};
        fourHourTimer.Elapsed += (sender, e) =>
        {
            //code to handle the elapsed event here
        };

        var span = time - DateTime.Now;
        var timer = new Timer {Interval = span.TotalMilliseconds, AutoReset = false};
        timer.Elapsed += (sender, e) => { fourHourTimer.Start();};
        timer.Start();
    }

希望这就是你需要的。

票数 8
EN

Stack Overflow用户

发布于 2016-06-06 20:41:57

这里有两个问题。

有关如何在指定时间启动计时器(这称为调度)的信息,请参见例如this.

  • How to -
  1. target time of possibly running timer。

调度(假设您的软件将会运行)基本上是在用户完成输入时创建计时器。如果用户更改了时间,您必须停止计时器,并使用新的时间重新启动它。

关于重新评估,同样的策略:每次用户改变值时,创建并启动新的计时器,考虑计时器正在运行和已经过去的时间。

所以基本上它将是2个计时器,其中一个用于启动另一个。

伪码:

代码语言:javascript
复制
 DispatcherTimer _scheduler;
 DispatcherTimer _timer;
 DateTime _start;
 TimeSpan _duration;

 // call this when specified time is changed
 void Schedule(DateTime time)
 {
     _start = time;
     // prevent any logic to run if timer is counting duration
     if(_timer != null)
         return;
     // stop scheduler
     if(_scheduler != null)
         _scheduler.Stop();
     // create new scheduler
     _scheduler = new DispatcherTimer { Interval = _start - DateTime.Now };
     _scheduler.Tick = (s, e) =>
     {
         Start(_duration); // here scheduler will start timer
         _scheduler.Stop(); // after that you don't need scheduler anymore
         _scheduler = null;
     }
     _scheduler.Start();
 }

 // call this when duration is changed
 void Start(TimeSpan duration)
 {
     _duration = duration;
     // prevent from running before starting time
     if(DateTime.Now < _start)
         return;
     // stop running timer
     if(_timer != null)
         _timer.Stop();
     // create timer to count duration including already expired time
     _timer = new DispatcherTimer { Interval = _duration - (DateTime.Now - _start) };
     _timer.Tick = (s, e) =>
     {
         ... // whatever
         _timer.Stop(); // clean up
         _timer = null;
     }
     _timer.Start();
 }

我使用DispatcherTimer来避免在启动另一个DispatcherTimer时调用。应该从UI线程(例如TextChanged事件处理程序)调用Schedule()Start()

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37656707

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档