我正在寻找创建一个高频回调线程。本质上,我需要一个以常规高频(高达 100Hz)间隔执行的函数。我意识到windows有一个正常的线程执行切片是~15ms。我想指定一个可以快于 15 毫秒的常规间隔。
这就是我想要完成的。我有一个外部设备需要以一定的时间间隔发送消息。间隔因情况而异。我希望我永远不需要超过 100Hz (10ms) 的消息速率。
我当然可以实现一个自旋循环,但是,我希望有一个不需要这么多资源浪费的解决方案。
提供的问题/答案链接无法解决此问题。虽然我同意这个问题已经以几种不同的方式提出,但还没有一个好的解决方案可以真正解决这个问题。
提供的大多数答案都涉及使用 Stopwatch 并手动执行计时任务,这完全是 CPU 密集型的。唯一可行的解决方案是使用多媒体计时器,正如 Haans 提到的那样,它存在一些缺陷。我找到了另一种解决方案,但我将在下面添加。我目前不知道其中的陷阱,但我计划进行一些测试和研究。我仍然对有关解决方案的评论感兴趣。
通过 WINAPI 调用
BOOL WINAPI CreateTimerQueueTimer(
_Out_ PHANDLE phNewTimer,
_In_opt_ HANDLE TimerQueue,
_In_ WAITORTIMERCALLBACK Callback,
_In_opt_ PVOID Parameter,
_In_ DWORD DueTime,
_In_ DWORD Period,
_In_ ULONG Flags
);
和
BOOL WINAPI DeleteTimerQueueTimer(
_In_opt_ HANDLE TimerQueue,
_In_ HANDLE Timer,
_In_opt_ HANDLE CompletionEvent
);
链接 - http://msdn.microsoft.com/en-us/library/windows/desktop/ms682485%28v=vs.85%29.aspx 我正在使用 PInvoke 来完成此操作。然而,在处理多媒体定时器时也需要这样做。
我的 PInvoke 签名给那些感兴趣的人。 Pinvoke 链接
[DllImport("kernel32.dll")]
static extern bool CreateTimerQueueTimer(out IntPtr phNewTimer,
IntPtr TimerQueue, WaitOrTimerDelegate Callback, IntPtr Parameter,
uint DueTime, uint Period, uint Flags);
// This is the callback delegate to use.
public delegate void WaitOrTimerDelegate (IntPtr lpParameter, bool TimerOrWaitFired);
[DllImport("kernel32.dll")]
static extern bool DeleteTimerQueueTimer(IntPtr TimerQueue, IntPtr Timer,
IntPtr CompletionEvent);
使用 CreateTimerQueueTimer 启动计时器回调。使用 DeleteTimerQueueTimer 停止计时器回调。这有点灵活,因为您也可以创建自定义队列。但是,如果只需要一个实例,最简单的实现是使用默认队列。
我使用带有旋转环的秒表测试了这个解决方案,我收到的关于计时的结果几乎相同。但是,我的机器上的 CPU 负载明显不同。
带自旋循环的秒表 - 约 12-15% 的恒定 CPU 负载(大约是我的一个内核的 50%) CreateTimerQueueTimer - 约 3-4% 的恒定 CPU 负载
我还觉得使用 CreateTimerQueueTimer 选项可以减少代码维护。因为它不需要将逻辑添加到您的代码流中。