WPF DispatcherTimer在恢复时没有时间

时间:2015-06-02 11:33:33

标签: c# wpf timer

当您在DispatcherTimer中将属性IsEnabled设置为false时,假设计时器在后台保持其状态,或者它被停止并重置?在以下示例中,计时器间隔为5秒,如果运行应用程序并单击按钮以在4秒时禁用计时器,并且再次单击按钮以在7秒启用它(例如),则计时器事件一秒钟后不会在8秒被解雇,而是在12s = 7s + 5s时被解雇。似乎timer.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";
        }
    }

}
}

2 个答案:

答案 0 :(得分:0)

无论是通过调用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;
        }
    }
}

答案 1 :(得分:0)

我知道它已经过了很长时间但是我正在使用这个例子并注意到为了使它正确,你需要进行一次小改动。

ToogleTimer()功能中,而不是调用_stopWatch。重新启动()调用_stopWatch。开始()

不同之处在于,如果您在每次重新启动秒表时再次在1个间隔内暂停更多次,则在上面的代码中会有副作用(它应该仅在调度员的Tick事件内重置)。