| 類別 | 命名空間 | 適用場景 | 精確度 | 執行緒模型 | 備註 |
|---|---|---|---|---|---|
| System.Windows.Forms.Timer | System.Windows.Forms | WinForms UI 簡單定時 | 低 (~55ms) | UI 執行緒 (訊息迴圈) | 需有訊息泵,Console App 無法使用 |
| System.Threading.Timer | System.Threading | 背景工作、高頻率、無 UI | 高 | ThreadPool 執行緒 | 輕量、無事件模型,需自行處理同步 |
| System.Timers.Timer | System.Timers | Server-side、WinForms/WPF、需事件模型 | 高 | ThreadPool 執行緒 (Elapsed 事件) | 支援 SynchronizingObject 回 UI 執行緒,功能最完整 |
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 執行緒,避免跨執行緒存取例外。Elapsed += 只執行一次,或在重新設定前先 -=。Elapsed 內未捕獲的例外會終止 Timer (舊版) 或被 ThreadPool 忽略 (新版),務必在事件處理函式內部 try-catch 並記錄日誌。AutoReset=true 會導致並行執行。解法:事件內先 _timer.Stop(),處理完再 _timer.Start(),或改用 AutoReset=false 手動重啟。Stop() 並 Dispose(),釋放 ThreadPool 佇列項目。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