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

C#定时器需求求助:按钮按下后分时段触发不同事件并自动停止

用C# Timer实现分阶段触发事件的解决方案

嘿,这个需求挺常见的,用System.Timers.Timer就能轻松搞定——既不会阻塞UI线程,还能精准控制时间节点。我给你写个完整的WinForms示例,直接就能用:

核心思路

用一个Timer每秒触发一次,记录已经流逝的秒数,根据不同的时间点触发对应的事件,到30秒时自动停止Timer。

完整代码示例

using System;
using System.Timers;
using System.Windows.Forms;

namespace TimerDemo
{
    public partial class MainForm : Form
    {
        // 声明Timer和秒数计数器
        private System.Timers.Timer _timer;
        private int _elapsedSeconds = 0;

        public MainForm()
        {
            InitializeComponent();
            // 初始化Timer,间隔设为1秒(1000毫秒)
            _timer = new System.Timers.Timer(1000); 
            _timer.Elapsed += Timer_Elapsed;
            _timer.AutoReset = true; // 设置为自动重复触发
        }

        // 按钮点击事件:启动整个计时流程
        private void btnStart_Click(object sender, EventArgs e)
        {
            // 重置计数器并启动Timer
            _elapsedSeconds = 0;
            _timer.Start();
            MessageBox.Show("计时已开始!");
        }

        // Timer触发的核心逻辑处理
        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            _elapsedSeconds++;

            // 按时间节点执行对应操作
            switch (_elapsedSeconds)
            {
                case 10:
                    ExecuteFirstEvent();
                    break;
                case 20:
                    ExecuteSecondEvent();
                    break;
                case 30:
                    _timer.Stop();
                    ExecuteStopAction();
                    break;
            }
        }

        // 自定义事件1:10秒时触发
        private void ExecuteFirstEvent()
        {
            // 注意:如果要更新UI,必须跨线程调用避免异常
            this.Invoke((MethodInvoker)delegate
            {
                lblStatus.Text = "10秒事件已触发!";
            });
            Console.WriteLine("触发10秒事件");
        }

        // 自定义事件2:20秒时触发
        private void ExecuteSecondEvent()
        {
            this.Invoke((MethodInvoker)delegate
            {
                lblStatus.Text = "20秒事件已触发!";
            });
            Console.WriteLine("触发20秒事件");
        }

        // 30秒到期时的停止操作
        private void ExecuteStopAction()
        {
            this.Invoke((MethodInvoker)delegate
            {
                lblStatus.Text = "计时已停止(30秒到期)";
            });
            Console.WriteLine("Timer已停止");
        }
    }
}

关键说明

  • 为什么选System.Timers.Timer?因为它在后台线程运行,不会卡住你的UI界面;如果是WPF场景,可以改用DispatcherTimer,核心逻辑完全一致。
  • 线程安全处理:Timer的Elapsed事件是在非UI线程触发的,所以更新UI控件(比如标签、按钮)时,必须用Invoke切换回UI线程,避免跨线程操作异常。
  • 灵活调整:如果不需要每秒触发,也可以把Timer间隔设为10000毫秒(10秒),用计数器记录触发次数——第1次触发10秒事件,第2次触发20秒事件,第3次停止Timer,这种方式更高效,但每秒触发的模式扩展性更强。

不推荐的替代方案

有人可能会想到用三个独立的Timer分别设置10、20、30秒间隔,但这种方式管理成本高,比如中途要取消计时的话,得同时停止三个Timer,远不如单个Timer统一控制清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:16:26