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

VC++ 定時任務實作方案對比:WM_TIMER、可等待計時器、系統排程器三種模式優劣分析

     編輯:關於VC++

前言:定時任務的核心需求

在未來特定時間點執行代碼。三種主流方案:

  1. WM_TIMER:視窗訊息機制,簡單但精度低、優先級低
  2. Waitable Timer (Kernel Object):高精度、可同步、需執行緒配合
  3. 系統排程器:持久化、跨進程、但依賴外部服務

方案一:WM_TIMER (最常用)

API


// 啟動
UINT_PTR SetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc);
// 停止
BOOL KillTimer(HWND hWnd, UINT_PTR uIDEvent);

MFC 封裝


// 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 執行緒

適用場景

  • UI 週期性更新 (狀態列、時鐘、動畫)
  • 短時輪詢 (檢查檔案、網路狀態)
  • 精度要求不高的背景任務

方案二:可等待計時器 + 專用執行緒 (高精度/同步)

核心 API


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`)。

缺點

  • 依賴「工作排程器」服務 (可被停用)
  • 需管理員權限註冊
  • 介面複雜 (COM)、部署麻煩
  • 難以與應用程式狀態同步

適用場景

  • 系統級維護任務 (備份、清理、更新)
  • 電腦關機/重啟後自動執行
  • 跨應用程式的集中排程

綜合選型建議

需求推薦方案備註
UI 週期更新、簡單輪詢WM_TIMERSetTimer/KillTimer 最簡潔
高精度週期任務、後台運算Waitable Timer + Thread精度 1ms 級,不阻塞 UI
系統級、持久化、跨重啟Task Scheduler COM需管理員權限,生產環境謹慎
單次延遲執行WM_TIMER (一次性) 或 CreateTimerQueueTimerTimer Queue 輕量、無需專用執行緒

進階:Timer Queue Timer (輕量級替代)


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);

系統管理執行緒池,無需自建執行緒,適合大量零星定時任務。

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