You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

切换页面返回后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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 00:52:56