WPF DispatcherTimer 在恢复时不保持时间
WPF DispatcherTimer doesn't keep time when resumed
当您在 DispatcherTimer 中将 属性 IsEnabled 设置为 false 时,假设计时器会在后台保持其状态,或者它会停止并重置?在下面的示例中,定时器间隔为 5 秒,如果您 运行 应用程序,如果您单击按钮以在 4 秒时禁用定时器,如果您再次单击该按钮以在 7 秒时启用它(例如) , 计时器事件不会在一秒后的 8s 时触发,而是在 12s = 7s + 5s 时触发。 timer.IsEnabled=false 似乎重置了计时器间隔。有没有其他方法在禁用时保持定时器状态?
该应用程序有两个标签 timerLabel 和 statusLabel 以及按钮。我这里没有足够的声誉点数来 post 图片。
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;
}
}
}
我知道它已经过去很长时间了,但我在使用这个示例时注意到要使其正确,您需要进行 1 处小改动。
在 ToogleTimer() 函数中而不是调用 _stopWatch.Restart() 调用 _stopWatch.Start()。
不同之处在于,在上面的代码中,如果您在 1 个间隔内暂停更多次,将会产生副作用,因为每次您恢复秒表都会重置(它应该只在 dispathcer 的 Tick 事件中重置)。
当您在 DispatcherTimer 中将 属性 IsEnabled 设置为 false 时,假设计时器会在后台保持其状态,或者它会停止并重置?在下面的示例中,定时器间隔为 5 秒,如果您 运行 应用程序,如果您单击按钮以在 4 秒时禁用定时器,如果您再次单击该按钮以在 7 秒时启用它(例如) , 计时器事件不会在一秒后的 8s 时触发,而是在 12s = 7s + 5s 时触发。 timer.IsEnabled=false 似乎重置了计时器间隔。有没有其他方法在禁用时保持定时器状态?
该应用程序有两个标签 timerLabel 和 statusLabel 以及按钮。我这里没有足够的声誉点数来 post 图片。
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;
}
}
}
我知道它已经过去很长时间了,但我在使用这个示例时注意到要使其正确,您需要进行 1 处小改动。
在 ToogleTimer() 函数中而不是调用 _stopWatch.Restart() 调用 _stopWatch.Start()。
不同之处在于,在上面的代码中,如果您在 1 个间隔内暂停更多次,将会产生副作用,因为每次您恢复秒表都会重置(它应该只在 dispathcer 的 Tick 事件中重置)。