高頻度のコールバック スレッドを作成しようとしています。基本的に、定期的な高周波 (最大 100Hz) 間隔で実行する関数が必要です。Windows の通常のスレッド実行スライスは ~15ms です。15ms よりも速くなる定期的な間隔を指定したいと思います。
これが私が達成しようとしていることです。特定の間隔でメッセージを送信する必要がある外部デバイスがあります。間隔は状況により変動します。100Hz (10ms) を超えるメッセージ レートは必要ないと思います。
もちろん、スピン ループを実装することもできますが、無駄なリソースをあまり必要としないソリューションがあることを期待していました。
質問/回答への提供されたリンクは、この質問を解決しません。質問がいくつかの異なる方法で尋ねられたことに同意しますが、実際に問題を解決する良い解決策はありませんでした.
提供された回答のほとんどは、ストップウォッチを使用してタイミングタスクを手動で実行することについて話していますが、これは完全に 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 署名。 ピンヴォーク リンク
[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 を使用します。カスタム キューも作成できるため、これはある程度柔軟です。ただし、単一のインスタンスのみが必要な場合の最も簡単な実装は、デフォルト キューを使用することです。
ストップウォッチとスピン ループを使用して、このソリューションをサイド 1 と一緒にテストしましたが、タイミングに関して受け取った結果はほぼ同じでした。ただし、私のマシンでは CPU 負荷が大幅に異なりました。
スピンループ付きストップウォッチ - ~12-15% の一定の CPU 負荷 (私のコアの約 50%) CreateTimerQueueTimer - ~3-4% の一定の CPU 負荷
また、CreateTimerQueueTimer オプションを使用すると、コードのメンテナンスが軽減されると思います。コード フローにロジックを追加する必要がないためです。