WPF DispatcherTimer在恢复时不保持时间
本文关键字:时间 DispatcherTimer 恢复 WPF | 更新日期: 2023-09-27 17:52:46
当你在DispatcherTimer中设置属性IsEnabled为false时,假设计时器在后台保持其状态,或者它被停止并重置?在下例中,定时器间隔为5s,如果运行应用程序并在5s时单击按钮禁用定时器,如果再次单击按钮以在7s时启用定时器(例如),则计时器事件不会在一秒后的8s时触发,而是在12s = 7s + 5s时触发。似乎那个计时器。IsEnabled=false重置定时器间隔。当禁用时,是否有其他方法保持定时器状态?
应用程序有两个标签timerLabel和statusLabel以及按钮。我在这里没有足够的声望点来发布图片。
namespace WpfApplication1 {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
int ticksCounter = 0;
System.Windows.Threading.DispatcherTimer timer;
private void Window_Loaded(object sender, RoutedEventArgs e) {
timer = new System.Windows.Threading.DispatcherTimer();
timer.Tick += new EventHandler(timer_Tick);
timer.Interval = new TimeSpan(0, 0, 0, 5, 0); // Sets 5 s. interval
timer.Start();
}
private void timer_Tick(object sender, EventArgs e) {
ticksCounter ++;
timeLabel.Content = "Ticks = " + ticksCounter.ToString();
}
private void button_Click(object sender, RoutedEventArgs e) {
if (timer.IsEnabled) {
timer.IsEnabled = false;
statusLabel.Content = "OFF";
boton.Content = "Enable";
}
else {
timer.IsEnabled = true;
statusLabel.Content = "ON";
boton.Content = "Disable";
}
}
}
}
DispatcherTimer
在重启时总是重新开始计时,无论是通过调用Start()
还是将IsEnabled
设置为true
。如果您希望计时器从间隔的中间恢复,则需要自己实现它。例如,通过维护一个Stopwatch
来测量从最近一次滴答开始经过的时间,并在重新启动它时减去第一个间隔的时间,在Tick
事件处理程序中将间隔恢复为所需的常规间隔。
下面的代码示例说明了基本思想:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
_timer = new DispatcherTimer();
_timer.Tick += _timer_Tick;
}
void _timer_Tick(object sender, EventArgs e)
{
_timer.Interval = _baseInterval;
_stopWatch.Restart();
}
private TimeSpan _baseInterval = TimeSpan.FromSeconds(5);
private DispatcherTimer _timer;
private Stopwatch _stopWatch = new Stopwatch();
// Call from appropriate location to toggle timer, e.g. in a button's
// Click event handler.
private void ToggleTimer()
{
if (_timer.IsEnabled)
{
_timer.IsEnabled = false;
_stopWatch.Stop();
button1.Content = "Start";
}
else
{
_timer.Interval = _baseInterval - _stopWatch.Elapsed;
_stopWatch.Restart();
_timer.IsEnabled = true;
}
}
}
我知道已经过去很长时间了,但我使用这个例子并注意到,为了使它正确,你需要一个小的改变。
在 togletimer ()函数中代替调用_stopWatch, Restart() call _stopWatch.Start()。不同之处在于,在上面的代码中,如果您在1个间隔内暂停多次,则会产生副作用,因为每次恢复秒表时都会重置(它应该仅在调度程序的Tick事件中重置)。