需求:每隔固定間隔 (如 10ms) 執行背景工作。常見兩種寫法:while(true){Thread.Sleep(10);} 與 System.Timers.Timer。本文實測記憶體佔用、執行緒數、Handle 數與實際觸發精度,給出明確選型建議。
// Thread.Sleep 版
while (true) { Thread.Sleep(10); /* 工作邏輯 */ }
// Timer 版
var timer = new System.Timers.Timer(10);
timer.Elapsed += (s, e) => { /* 工作邏輯 */ };
timer.Start();
測試執行 100,000 次間隔,記錄起迄時間與資源佔用。
| 指標 | Thread.Sleep | Timer | 勝出 |
|---|---|---|---|
| Work Set (工作集) | 6.59 MB | 8.99 MB | Thread.Sleep |
| Virtual Bytes (虛擬位元組) | 104.30 MB | 114.98 MB | Thread.Sleep |
| Page File Bytes (分頁檔) | 7.14 MB | 11.44 MB | Thread.Sleep |
| Thread Count (執行緒數) | 3 | 4 | Thread.Sleep |
| Handle Count | 95 | 115 | Thread.Sleep |
| 指標 | Thread.Sleep | Timer |
|---|---|---|
| 開始時間 | 11:53:37.432 | 11:53:37.416 |
| 結束時間 | 12:19:36.713 | 12:19:37.555 |
| 實際總耗時 | ~1559 秒 | ~1560 秒 |
| 平均間隔 | ~15.59 ms | ~15.60 ms |
Thread.Sleep(10) 僅保證「至少睡 10ms」,實際受 OS 排程器影響 (Windows 時脈預設 15.6ms);Timer 同樣受限於執行緒池排程。需要精確到毫秒級、不可漂移? → 是 → 專用排程庫 / Multimedia Timer (極少數場景)
↓ 否
單純背景輪詢、容忍 15ms+ 抖動? → 是 → Thread.Sleep 簡單、資源省
↓ 否
需支援動態調整間隔、啟停、異常處理? → 是 → System.Timers.Timer / System.Threading.Timer
↓ 否
企業級排程 (Cron、持久化、叢集、監控)? → 是 → Quartz.NET / Hangfire
簡單輪詢首選 Thread.Sleep (資源最省);需控制靈活性用 Timer;**任何對精度有要求的場景,請直接使用成熟排程框架**,勿自行造輪子。