切换页面返回后System.Timers.Timer每秒计数2秒的问题求助
WPF计时器切换页面后计数翻倍问题修复
问题根源
你的问题核心是每次进入Page2都会创建新的Timer实例,且旧Timer未被销毁仍在后台运行,同时静态变量started会触发新Timer启动,导致多个Timer同时触发Elapsed事件,每秒多次修改计数器。另外timer.Elapsed += OnTimerElapsed每次实例化页面都会重复订阅,但更致命的是多个Timer并行运行。
修复方案1:页面独立计时(每次进入页面重置状态)
将Timer和计数器改为页面实例级变量,在页面卸载时彻底清理Timer:
public partial class Page2 : Page { private System.Timers.Timer _timer; private int _counter = 0; private int _minutes = 0; private bool _isStarted = false; public Page2() { InitializeComponent(); czaso.Text = $"{_minutes}:{_counter:00}"; _timer = new System.Timers.Timer(1000); _timer.Elapsed += OnTimerElapsed; _timer.AutoReset = true; } private void OnTimerElapsed(object sender, ElapsedEventArgs e) { czaso.Dispatcher.Invoke(() => { _counter++; if (_counter > 59) { _minutes += 1; _counter = 0; } czaso.Text = $"{_minutes}:{_counter:00}"; if (_counter == 95) { NavigationService.Navigate(new Uri("/MainWindow.xaml", UriKind.Relative)); } }); } private void LpmCzas(object sender, RoutedEventArgs e) { _isStarted = true; _timer.Start(); } protected override void OnUnloaded(RoutedEventArgs e) { base.OnUnloaded(e); if (_timer != null) { _timer.Elapsed -= OnTimerElapsed; _timer.Stop(); _timer.Dispose(); _timer = null; } } }
修复方案2:全局共享计时(切换页面保留计时状态)
如果需要在页面切换时继续计时,使用单例Timer确保全局唯一实例:
public partial class Page2 : Page { private static System.Timers.Timer _globalTimer; private static int _counter = 0; private static int _minutes = 0; private static bool _isStarted = false; public Page2() { InitializeComponent(); czaso.Text = $"{_minutes}:{_counter:00}"; // 仅第一次初始化Timer if (_globalTimer == null) { _globalTimer = new System.Timers.Timer(1000); _globalTimer.Elapsed += OnGlobalTimerElapsed; _globalTimer.AutoReset = true; } } private void OnGlobalTimerElapsed(object sender, ElapsedEventArgs e) { Application.Current.Dispatcher.Invoke(() => { _counter++; if (_counter > 59) { _minutes += 1; _counter = 0; } // 更新当前激活的Page2的UI var activePage = Application.Current.Windows.OfType<Window>() .FirstOrDefault(w => w.IsActive)?.Content as Page2; if (activePage != null) { activePage.czaso.Text = $"{_minutes}:{_counter:00}"; if (_counter == 95) { activePage.NavigationService.Navigate(new Uri("/MainWindow.xaml", UriKind.Relative)); } } }); } private void LpmCzas(object sender, RoutedEventArgs e) { _isStarted = true; _globalTimer.Start(); } }
关键修复要点
- 移除Timer的
static修饰符(或用单例模式),避免重复创建Timer实例。 - 在页面卸载时执行
Stop()、取消事件订阅、Dispose(),彻底清理旧Timer资源。 - 根据业务需求选择实例级或全局状态管理,避免静态变量导致的状态混乱。
内容的提问来源于stack exchange,提问作者Miloo
相关产品推荐
相关产品推荐

