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";
        }
    }
}
}

WPF DispatcherTimer在恢复时不保持时间

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事件中重置)。