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

VC++ 定時任務實現方案對比:WM_TIMER、等待型計時器、系統排程

     編輯:VC 教學

前言

Windows 下實現「未來某時刻執行任務」有多種方案。本文對比三種主流做法:**WM_TIMER 視窗計時器**、**核心物件等待型計時器**、以及**系統排程任務**,分析精度、資源消耗、適用場景、程式碼複雜度,並給出推薦選型指南。

方案一:WM_TIMER 視窗計時器

API


UINT_PTR SetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc);
BOOL KillTimer(HWND hWnd, UINT_PTR uIDEvent);

特點

  • 有視窗:hWnd 指定接收 WM_TIMER 的視窗,lpTimerFunc = NULL,訊息佇列處理。
  • 無視窗:hWnd = NULL,需提供 TIMERPROC 回呼函數,系統建立獨立執行緒呼叫。
  • MFC 封裝:CWnd::SetTimer/KillTimer 省略 hWnd。

優缺點

優點缺點
API 簡單、無需額外執行緒管理**精度低**:系統約 10-15ms 解析度,受訊息佇列擁塞影響
自動在 UI 執行緒處理 (有視窗模式)**權限低**:WM_TIMER 為低優先級訊息,系統忙碌時可能被丟棄/延遲
支援週期性觸發需輪詢/判斷時間點,浪費 CPU (若在 OnTimer 中做複雜判斷)

方案二:等待型計時器 — 推薦用於高精度/後台任務

核心 API


HANDLE CreateWaitableTimer(
    LPSECURITY_ATTRIBUTES lpTimerAttributes, // 通常 NULL
    BOOL bManualReset,                       // FALSE = 自動重置 (單次)
    LPCTSTR lpTimerName                      // 可選名稱
);

BOOL SetWaitableTimer(
    HANDLE hTimer,
    const LARGE_INTEGER* pDueTime,  // 絕對時間 (正數) 或相對時間 (負數,100ns 為單位)
    LONG lPeriod,                   // 週期 (ms),0 = 單次
    PTIMERAPCROUTINE pfnCompletionRoutine, // APC 回呼 (可選)
    LPVOID lpArgToCompletionRoutine,       // 回呼參數
    BOOL fResume                         // TRUE = 喚醒休眠系統
);

DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds); // INFINITE 等待

典型使用模式:專用執行緒 + 等待型計時器


DWORD WINAPI TimerThread(LPVOID pParam)
{
    HANDLE hTimer = CreateWaitableTimer(NULL, FALSE, NULL);
    LARGE_INTEGER due;
    due.QuadPart = -10000000; // 相對 1 秒 (負數 = 相對時間,單位 100ns)

    SetWaitableTimer(hTimer, &due, 1000, NULL, NULL, FALSE); // 每 1 秒週期

    while (true) {
        DWORD ret = WaitForSingleObject(hTimer, INFINITE);
        if (ret == WAIT_OBJECT_0) {
            // 執行定時任務
            DoPeriodicWork();
        }
    }
    // 清理 (實際需退出機制)
    CloseHandle(hTimer);
    return 0;
}

優缺點

優點缺點
**高精度**:100ns 解析度,受系統排程器管理,準時度極高需建立專用執行緒,增加複雜度
**可喚醒休眠系統** (fResume=TRUE)APC 回呼需理解 APC 機制 (警示性等待)
支援絕對時間 (UTC FILETIME) 觸發手動重置模式需自行重置
無視窗/訊息佇列依賴,適合服務/主控台程式

方案三:系統排程任務

  • 透過 WinExec("at ...")、schtasks、COM ITaskScheduler 註冊系統排程。
  • **缺點**:依賴「工作排程器」服務,易被管理員停用/刪除、需管理員權限、除錯困難、進程隔離導致進程間通訊複雜。
  • **適用**:真正的「每天凌晨 3 點備份」等系統級維護任務,非應用程式內部邏輯。

方案對比總表

維度WM_TIMERWaitable TimerSystem Scheduler
精度~15ms100ns秒級
資源極低一執行緒 + Handle系統服務
適用程式類型GUI (有視窗)GUI/服務/主控台系統維護
週期/單次均支援均支援均支援
喚醒休眠否是是 (喚醒定時器)
實作複雜度低中高

選型指南

  1. GUI 簡單週期性 UI 更新 (如閃爍、進度條) → WM_TIMER (MFC SetTimer)。
  2. 高精度、後台計算、無視窗、需喚醒休眠 → 等待型計時器 + 專用執行緒 (本文推薦核心方案)。
  3. 系統級定時維護** (備份、清理、報表) → Windows 工作排程器 (schtasks/COM)。
  4. 現代 C++ (C++11+) → std::chrono + std::thread + sleep_until / condition_variable,或 Boost.Asio steady_timer,跨平台且型別安全。

總結

WM_TIMER 簡單但精度低、易丟失;等待型計時器為**高精度、可靠、無視窗依賴**的核心方案,適合服務與精密控制;系統排程屬不同層面。實務中,**GUI 用 WM_TIMER,核心邏輯/服務用 Waitable Timer**,兩者互補。

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