System.Threading.Timer(或 Task.Delay)優於 while(true)+Thread.Sleep,除非極少數需精確控制執行間隔、無等待唤醒機制的場景。
| 維度 | Timer / Task.Delay | while(true) + Sleep |
|---|---|---|
| CPU 佔用 | 極低(內核定時器/IOCP 排隊) | Sleep 期間為 0,但醒來/休眠切換有開銷 |
| 精確度 | 毫秒級(受線程池調度影響) | 同樣受調度影響,易產生累積誤差 |
| 異常處理 | 回調內 try-catch,不影響下次觸發 | 需手動 try-catch 包裹循環體,否則線程死掉 |
| 取消/暫停 | timer.Change(Timeout.Infinite, ...) / CancellationToken | 需共享 volatile bool 标志位,配合 Sleep 檢查 |
| 資源釋放 | Dispose() 釋放內核對象 | 線程結束需 Join(),否則殭屍線程 |
| 適用場景 | 定時任務、輪詢、延遲執行 | 極簡輪詢、無線程池環境、需緊湊控制邏輯 |
// .NET 6+ 周期性任務
var cts = new CancellationTokenSource();
var task = Task.Run(async () => {
while (!cts.Token.IsCancellationRequested) {
await DoWorkAsync();
try { await Task.Delay(TimeSpan.FromSeconds(30), cts.Token); }
catch (OperationCanceledException) { break; }
}
}, cts.Token);
// 停止
cts.Cancel();
await task;
WaitHandle.WaitAny)。SpinWait 或專用定時器。