以下是场景:
有一个Textbox,用户在其中输入DispatcherTimer必须开始的时间。定时器设置为始终运行4小时,Timer.Tick事件播放声音。假设计时器在04:00:00 (HH:mm:ss)开始,它应该运行到8:00:00,然后停止。然后,当用户将时间更改为09:00:00时。计时器应该运行到13:00:00,以此类推。
如何才能做到这一点?我不能运行1分钟的计时器来检查正确的时间,因为这会对系统造成很大的负担。
感谢所有的帮助。提前谢谢你。
发布于 2016-06-06 20:23:04
下面的方法根据提供的日期时间(即输入到文本框中的时间)启动一个初始计时器。当时间到达时,它启动一个二级计时器,从那时起每四个小时触发一次。
我使用的是System.Timers定时器而不是Sytem.Threading定时器(因为具有讽刺意味的是system.threading定时器不是线程安全的!)
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();
}希望这就是你需要的。
发布于 2016-06-06 20:41:57
这里有两个问题。
有关如何在指定时间启动计时器(这称为调度)的信息,请参见例如this.
调度(假设您的软件将会运行)基本上是在用户完成输入时创建计时器。如果用户更改了时间,您必须停止计时器,并使用新的时间重新启动它。
关于重新评估,同样的策略:每次用户改变值时,创建并启动新的计时器,考虑计时器正在运行和已经过去的时间。
所以基本上它将是2个计时器,其中一个用于启动另一个。
伪码:
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()。
https://stackoverflow.com/questions/37656707
复制相似问题