以下是该方案:
用Textbox
用户输入DispatcherTimer
必须开始的时间。 Timer设置为始终运行4小时,Timer.Tick事件播放声音。让我们说计时器从04:00:00(HH:mm:ss)开始,它应该运行到8:00:00然后停止。然后当用户改变时间时,让我们说到09:00:00。计时器应该运行到13:00:00,依此类推。
如何实现这一目标?我不能运行一个1分钟的计时器来继续检查正确的时间,因为这对系统来说非常沉重。
感谢所有帮助。提前谢谢。
答案 0 :(得分:5)
下面的方法启动一个初始计时器,其间隔基于提供的日期时间(即输入文本框的时间)。当达到时间时,它会启动一个辅助计时器,该计时器将从该点开始每四个小时启动一次。
我使用System.Timers Timer而不是Sytem.Threading Timer(因为具有讽刺意味的是,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();
}
希望这就是你所需要的。
答案 1 :(得分:1)
这里有2个问题。
调度(假设您的软件将运行)基本上是在用户完成输入时创建计时器。如果用户更改时间,您必须停止该计时器并使用新时间再次启动它。
关于重新评估,同样的策略:每次用户更改值时创建并启动新计时器,在计时器运行且已经过时的时候考虑。
所以基本上它将是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线程调用Schedule()
和Start()
(例如TextChanged
事件处理程序)。