在未來特定時間點執行代碼。三種主流方案:
// 啟動
UINT_PTR SetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc);
// 停止
BOOL KillTimer(HWND hWnd, UINT_PTR uIDEvent);
// CWnd::SetTimer (無 hWnd 參數)
UINT_PTR SetTimer(UINT nIDEvent, UINT nElapse, void (CALLBACK* lpfnTimer)(HWND, UINT, UINT_PTR, DWORD));
// 無回呼函數 → 收到 WM_TIMER 訊息,OnTimer 處理
| 優點 | 缺點 |
|---|---|
| 極簡單、無需額外執行緒 | 精度 ~10-15ms (系統時鐘中斷) |
| 自動處理訊息泵 | 低優先級,系統忙碌時可能丟失/延遲 |
| MFC 完整封裝 | 長時間任務阻塞 UI 執行緒 |
HANDLE CreateWaitableTimer(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset, LPCTSTR lpTimerName);
BOOL SetWaitableTimer(HANDLE hTimer, const LARGE_INTEGER* pDueTime, LONG lPeriod,
PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArg, BOOL fResume);
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
DWORD WINAPI TimerThread(LPVOID pParam) {
HANDLE hTimer = CreateWaitableTimer(NULL, FALSE, NULL);
LARGE_INTEGER due;
due.QuadPart = -10000000LL; // 1 秒 (100ns 單位,負數=相對時間)
SetWaitableTimer(hTimer, &due, 1000, NULL, NULL, FALSE); // 週期 1000ms
while (WaitForSingleObject(hTimer, INFINITE) == WAIT_OBJECT_0) {
// 執行定時任務
DoPeriodicWork();
}
CloseHandle(hTimer);
return 0;
}
// 啟動
AfxBeginThread(TimerThread, NULL);
| 優點 | 缺點 |
|---|---|
| 高精度 (100ns 解析度) | 需管理執行緒生命週期、同步 |
| 可喚醒休眠系統 (fResume=TRUE) | 複雜度高,錯誤難除錯 |
| 支援 APC 非同步回呼 | APC 需執行緒處於可提醒狀態 |
| 不阻塞 UI 執行緒 | 執行緒資源常駐 |
透過 `WinExec`/`CreateProcess` 呼叫 `schtasks.exe` 或 `at.exe`,或使用 Task Scheduler COM 介面 (`ITaskScheduler`)。
| 需求 | 推薦方案 | 備註 |
|---|---|---|
| UI 週期更新、簡單輪詢 | WM_TIMER | SetTimer/KillTimer 最簡潔 |
| 高精度週期任務、後台運算 | Waitable Timer + Thread | 精度 1ms 級,不阻塞 UI |
| 系統級、持久化、跨重啟 | Task Scheduler COM | 需管理員權限,生產環境謹慎 |
| 單次延遲執行 | WM_TIMER (一次性) 或 CreateTimerQueueTimer | Timer Queue 輕量、無需專用執行緒 |
HANDLE hTimerQueue = CreateTimerQueue();
HANDLE hTimer;
CreateTimerQueueTimer(&hTimer, hTimerQueue,
[](PVOID lpParam, BOOLEAN TimerOrWaitFired) {
// 任務代碼
}, NULL, 5000, 0, WT_EXECUTEDEFAULT); // 5秒後執行一次
// 清理
DeleteTimerQueueTimer(hTimerQueue, hTimer, INVALID_HANDLE_VALUE);
DeleteTimerQueue(hTimerQueue);
系統管理執行緒池,無需自建執行緒,適合大量零星定時任務。