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

C# WPF中使用Threading.Timer实现循环数秒后停止如何解决

问题根因

你在Timer_Start方法中声明的Timer是局部变量,方法执行结束后没有任何持有该Timer实例的存活引用,会被.NET垃圾回收器判定为可回收对象,回收后定时器自然就停止触发回调,这就是为什么代码只能运行几秒、触发几次Tick就失效的核心原因。
你之前尝试无限循环导致程序无法启动,是因为把循环逻辑写在了UI线程上,直接阻塞了UI消息循环,窗口自然无法正常加载、响应操作。

修复方案

方案1:修正现有System.Threading.Timer的写法

将Timer声明为窗口类的实例字段,保证它的生命周期和当前窗口一致,不会被意外回收:

// 声明为类实例字段,而非方法内局部变量
private Timer _coinTimer;
private int coins = 0;
private int cps = 1; // 每秒自动增加的金币数,可根据需求调整

public void Timer_Start()
{
    _coinTimer = new Timer(Tick, null, 100, 1000);
}

public MainWindow()
{
    InitializeComponent();
    Timer_Start();
}

public void Tick(object stateInfo)
{
    coins += cps;
    // 跨线程更新UI必须通过Dispatcher调度到UI线程执行,这部分你的写法是对的
    this.Dispatcher.Invoke(() =>
    {
        Score_Update();
    });
}

// 窗口关闭时释放Timer资源,避免内存泄漏
protected override void OnClosed(EventArgs e)
{
    _coinTimer?.Dispose();
    base.OnClosed(e);
}

方案2:使用WPF原生DispatcherTimer(更适配WPF场景)

WPF内置的DispatcherTimer运行在UI线程上,不需要手动做跨线程调度,写法更简洁,也不会出现跨线程访问UI的异常,做客户端定时逻辑优先选这个:

private DispatcherTimer _coinTimer;
private int coins = 0;
private int cps = 1;

public void Timer_Start()
{
    _coinTimer = new DispatcherTimer();
    _coinTimer.Interval = TimeSpan.FromSeconds(1); // 设置触发间隔为1秒
    _coinTimer.Tick += CoinTimer_Tick;
    _coinTimer.Start();
}

private void CoinTimer_Tick(object sender, EventArgs e)
{
    coins += cps;
    Score_Update(); // 运行在UI线程,无需额外调用Dispatcher.Invoke
}

public MainWindow()
{
    InitializeComponent();
    Timer_Start();
}

protected override void OnClosed(EventArgs e)
{
    _coinTimer?.Stop();
    base.OnClosed(e);
}
开发注意点
  • WPF的UI控件有严格的线程亲和性,只有创建控件的UI线程才能直接访问、修改控件属性,非UI线程操作控件必须通过Dispatcher调度。
  • 永远不要在UI线程上写无限循环、Thread.Sleep这类阻塞逻辑,会卡住UI消息泵,导致程序无响应。
  • 所有实现了IDisposable的对象(比如System.Threading.Timer),不需要使用时要主动调用Dispose释放资源。

内容的提问来源于stack exchange,提问作者Yuri O

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 08:42:28