You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用带名称与回调的高分辨率可等待定时器:Bug还是特性?

Windows高分辨率可等待定时器的名称与完成例程限制

这是Windows系统的已知特性,微软官方文档确实未明确标注这些限制,但高分辨率可等待定时器存在以下两个关键约束:

核心限制说明

  • 高分辨率可等待定时器不支持命名:无法通过CreateWaitableTimerExW同时指定定时器名称和CREATE_WAITABLE_TIMER_HIGH_RESOLUTION标志,否则会返回错误码0x57(参数错误)。这是因为命名定时器设计用于跨进程共享,而高分辨率定时器依赖硬件级别的高精度调度机制,无法支持跨进程场景。
  • 高分辨率可等待定时器不支持完成例程(回调):即使创建了无名称的高分辨率定时器,调用SetWaitableTimerEx或SetWaitableTimer传入完成例程参数也会返回0x57错误。高分辨率定时器的实现逻辑与普通可等待定时器不同,仅支持同步等待模式,无法触发异步回调。

对应问题分析

  1. 指定名称+高分辨率标志创建失败:完全符合上述第一个限制,参数组合非法,系统直接拒绝创建。
  2. 无名称高分辨率定时器无法设置完成例程:符合第二个限制,高分辨率定时器不支持异步回调机制,只能通过同步等待(如WaitForSingleObject)处理定时事件。
  3. 普通定时器操作正常:普通可等待定时器基于系统常规定时器队列,支持命名共享和完成例程,因此所有操作无异常。

解决方案建议

  • 如果必须使用高分辨率定时:只能创建无名称的高分辨率定时器,通过同步等待方式处理触发逻辑,放弃完成例程。
  • 如果需要完成例程或跨进程共享的命名定时器:只能放弃CREATE_WAITABLE_TIMER_HIGH_RESOLUTION标志,使用普通可等待定时器。

可复现代码

#include <iostream>
#include <windows.h>
#include <tchar.h>

void TimerRoutine(LPVOID lpArgToCompletionRoutine, DWORD dwTimerLowValue, DWORD dwTimerHighValue)
{
    HANDLE* hEvent = static_cast<HANDLE*>(lpArgToCompletionRoutine);
    if (hEvent != nullptr)
    {
        std::cout << "Test succeeded!\n";
        SetEvent(*hEvent);
    }
}

int main()
{
    constexpr int64_t COEFF{ -10'000 };
    constexpr int64_t TIMEOUT{ 5'000 };

    HANDLE hEvent = CreateEvent(nullptr, TRUE, FALSE, _T("AnEvent"));
    if (hEvent == nullptr)
    {
        DWORD err = GetLastError();
        std::cerr << "Failed to create an event object, error code = " << err << std::endl;
        return -1;
    }

    // Create high resolution waitable timer. Uncomment one of them and compare behavior.
    HANDLE hTimer = CreateWaitableTimerExW(nullptr, L"ATimer", CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
    // HANDLE hTimer = CreateWaitableTimerExW(nullptr, nullptr, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
    // HANDLE hTimer = CreateWaitableTimerExW(nullptr, L"ATimer", 0, TIMER_ALL_ACCESS);
    if (hTimer == nullptr)
    {
        DWORD err = GetLastError();
        std::cerr << "Failed to create a high resolution waitable timer with a name, error code = " << err << std::endl;
        CloseHandle(hEvent);
        return -1;
    }

    // Set timer with callback, relative timeout.
    LARGE_INTEGER dueTime;
    dueTime.QuadPart = TIMEOUT * COEFF;
    if (SetWaitableTimerEx(hTimer, &dueTime, 0, &TimerRoutine, &hEvent, nullptr, 0) == FALSE)
    {
        DWORD err = GetLastError();
        std::cerr << "Failed to set timer, error code = " << err << std::endl;
        CloseHandle(hTimer);
        CloseHandle(hEvent);
        return -1;
    }

    // Wait until event object is signaled from the timer callback.
    WaitForSingleObjectEx(hEvent, INFINITE, TRUE);

    CloseHandle(hTimer);
    CloseHandle(hEvent);

    return 0;
}

内容的提问来源于stack exchange,提问作者arin-berd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 04:50:30