首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 三大 Timer 比較與 System.Timers.Timer 完整使用範例

     編輯:關於C#

.NET 三種 Timer 差異總覽

類別命名空間適用場景精確度執行緒模型備註
System.Windows.Forms.TimerSystem.Windows.FormsWinForms UI 簡單定時低 (~55ms)UI 執行緒 (訊息迴圈)需有訊息泵,Console App 無法使用
System.Threading.TimerSystem.Threading背景工作、高頻率、無 UI高ThreadPool 執行緒輕量、無事件模型,需自行處理同步
System.Timers.TimerSystem.TimersServer-side、WinForms/WPF、需事件模型高ThreadPool 執行緒 (Elapsed 事件)支援 SynchronizingObject 回 UI 執行緒,功能最完整

System.Timers.Timer 完整範例 (WinForms)

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

namespace TimerDemo
{
    public partial class Form1 : Form
    {
        private readonly Timer _timer = new Timer();

        public Form1()
        {
            InitializeComponent();
            ConfigureTimer();
        }

        private void ConfigureTimer()
        {
            _timer.Interval = 1000;           // 1 秒
            _timer.AutoReset = true;          // true=週期性,false=單次
            _timer.Elapsed += OnTimerElapsed; // 訂閱事件
            // 若需在 UI 執行緒更新介面,設定 SynchronizingObject
            _timer.SynchronizingObject = this; 
        }

        private void OnTimerElapsed(object sender, ElapsedEventArgs e)
        {
            // 此處已在 UI 執行緒 (因 SynchronizingObject)
            lblTime.Text = DateTime.Now.ToString("HH:mm:ss.fff");
            // 若未設定 SynchronizingObject,需用 Invoke:
            // this.Invoke((Action)(() => lblTime.Text = DateTime.Now.ToString()));
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            _timer.Start(); // 等同 _timer.Enabled = true;
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            _timer.Stop();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _timer.Stop();
                _timer.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

關鍵屬性與事件

  • Interval:毫秒單位,建議 ≥ 50ms 避免 ThreadPool 壓力。
  • AutoReset:true 週期觸發,false 單次觸發後自動停用。
  • Elapsed:核心事件,sender 為 Timer 本身,e.SignalTime 為理論觸發時間。
  • SynchronizingObject:設為 Control 或 DispatcherObject 可自動封送至 UI 執行緒,避免跨執行緒存取例外。

常見陷阱與最佳實務

  1. 重複訂閱: 確保 Elapsed += 只執行一次,或在重新設定前先 -=。
  2. 例外吞沒: Elapsed 內未捕獲的例外會終止 Timer (舊版) 或被 ThreadPool 忽略 (新版),務必在事件處理函式內部 try-catch 並記錄日誌。
  3. 重疊執行: 若處理時間 > Interval,AutoReset=true 會導致並行執行。解法:事件內先 _timer.Stop(),處理完再 _timer.Start(),或改用 AutoReset=false 手動重啟。
  4. Dispose 時機: 表單關閉、服務停止時必須 Stop() 並 Dispose(),釋放 ThreadPool 佇列項目。

Console 應用程式使用範例

class Program
{
    static void Main()
    {
        var timer = new Timer(2000) { AutoReset = true };
        timer.Elapsed += (s, e) => Console.WriteLine($"Tick: {e.SignalTime:HH:mm:ss.fff}");
        timer.Start();
        Console.WriteLine("Press Enter to exit...");
        Console.ReadLine();
        timer.Dispose();
    }
}

參考資源

原文連結:https://www.bianceng.cn/Programming/csharp/201410/45596.htm

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved