WPF 调度程序计时器在重新启动时按间隔跳过

本文关键字:调度程序 计时器 重新启动 WPF | 更新日期: 2023-09-27 18:33:45

在过去的几天里,我一直在为此苦苦挣扎,希望你们都能帮助我。我正在创建一个 WPF 计时器应用程序,并使用调度程序计时器来以分钟为单位向上计数以跟踪时间。当我最初启动计时器时,它运行良好。但是,当我停止计时器,然后重新启动它时,它开始按 2 计数。如果我再做一次,它按 3 计数,依此类推。我不完全确定DispatcherTimer可以做什么,所以这是我真正可以使用一些帮助的地方。

这是单击"开始"按钮时调用的初始函数。

private void TimerStart(object sender, RoutedEventArgs e)
{
    if ((string) TimerBlock.Content == "--:--")
    {
        TimerBlock.Content = "00:00";
        TimerTray.Content = "00:00";
    }
    else
    {
        var timerString = TimerBlock.Content.ToString();
        _minute = Convert.ToInt32(timerString.Substring(0, 2));
        _hour = Convert.ToInt32(timerString.Substring(3, 2));
    }
    _timer.Interval = TimerBlock.Content.ToString();
    _timer.Tick += dispatcherTimer_tick;
    _timer.Start();
    TaskBarStop.IsChecked = false;
    TimerStatus.Content = "The Timer Has Started";
    TimerStatus.Foreground = System.Windows.Media.Brushes.DarkGreen;
    TimerTrayStatus.Content = "STARTED";
    TimerTrayStatus.Foreground = System.Windows.Media.Brushes.DarkGreen;
    StartButton.IsEnabled = false;
    StopButton.IsEnabled = true;
}

这是勾号。

private void dispatcherTimer_tick(object sender, EventArgs e)
{
    if (_minute++ == 60)
    {
        _minute = 0;
        _hour++;
    }
    if (_hour < 10 && _minute < 10)
        TimerBlock.Content = "0" + _hour + ":0" + _minute;
    else if (_hour < 10 && _minute >= 10)
        TimerBlock.Content = "0" + _hour + ":" + _minute;
    else if (_hour >= 10 && _minute < 10)
        TimerBlock.Content = _hour + ":0" + _minute;
    else
        TimerBlock.Content = _hour + ":" + _minute;
    TimerTray.Content = TimerBlock.Content;
    CommandManagaer.InvalidateRequerySuggested();
}

这是按下停止按钮时调用的方法。

private void TimerStop(object sender, RoutedEventArgs e)
{
    _timer.Stop();
    TaskBarStart.IsChecked = false;
    TimerStatus.Content = "The Timer Has Stopped";
    TimerStatus.Foreground = System.Windows.Media.Brushes.DarkRed;
    TimerTrayStatus.Content = "STOPPED";
    TimerTrayStatus.Foreground = System.Windows.Media.Brushes.DarkRed;
    StartButton.IsEnabled = true;
    StopButton.IsEnabled = false;
    using (var db = new TimerDb())
    {            
        var timer = TimerBlock.Content.ToString();
        var session = new TimerSession();
        if (db.TemporaryTimeActivities.Any())
            session.SetTimeActivity(timer);            
        else
            session.UpdateTime(timer);
    }
}
基本上,我

无法弄清楚这是否只是我忽略的小事情,或者我是否在其他地方搞砸了一些非常糟糕的事情。任何帮助将不胜感激。我在代码中放入了一些东西,导致每次重新启动时将间隔增加 1?

WPF 调度程序计时器在重新启动时按间隔跳过

您应该只附加一次 Tick 处理程序,而不是每次启动计时器时。

所以移动线

_timer.Tick += dispatcherTimer_tick;

TimerStart 方法中取出,并将其放在例如窗口或用户控件的构造函数中。

此外,还应确保计时器的Interval设置正确。看起来您想每分钟调用一次 Tick 处理程序,因此您应该相应地设置它:

_timer.Interval = TimeSpan.FromMinutes(1.0);

不自己计算分钟数,而是使用DateTimeTimeSpan结构也会更容易(也更准确(。使用 DateTime.Now 属性将开始时间存储在 TimerStart 方法中 DateTime 类型的字段中。

private DateTime started;
private void TimerStart(object sender, RoutedEventArgs e)
{
    ...
    started = DateTime.Now;
}

并利用 TimeSpan 类的字符串格式设置功能:

private void dispatcherTimer_tick(object sender, EventArgs e)
{
    var elapsedTime = DateTime.Now - started;
    TimerBlock.Content = elapsedTime.ToString(@"hh':mm");
    ...
}