ときどき (実行の約 50% で)、EnumDevices が戻るのに 5 ~ 10 秒かかります。通常はほぼ瞬時です。この種の行動に関する他の報告は見つかりませんでした。
物事がこれほど遅い場合は、stdout を見てプロファイリングしても問題ありません:) これ:
std::cout << "A";
directInput8Interface->EnumDevices(DI8DEVCLASS_GAMECTRL, MyCallback, NULL, DIEDFL_ATTACHEDONLY);
std::cout << "C";
...
BOOL CALLBACK MyCallback(LPCDIDEVICEINSTANCE, LPVOID)
{
std::cout << "B";
return DIENUM_CONTINUE;
}
デバイスの列挙を通じてランダムな時点でハングしているようです-コールバックがまったく呼び出される前になることもあれば、数回後に発生することもあれば、最後の呼び出しの後に発生することもあります。
これは明らかに単純化されたコードの塊です。私は実際に OIS 入力ライブラリ ( http://sourceforge.net/projects/wgois/ ) を使用しているので、コンテキストについては、ここで完全なソースを参照してください。
そこには特にフルーティーなものはないようですが、初期化の何かが原因である可能性があります.DI8については、それを見つけるのに十分な知識がありません.
なぜこんなに遅いのかについてのアイデアは大歓迎です!
編集:
etl トレース ファイルでハングをキャッチし、Windows パフォーマンス アナライザーで分析しました。EnumDevices
最終的に を呼び出し、 を呼び出し、DInput8.dll!fGetProductStringFromDevice
を呼び出しHIDUSB.SYS!HumCallUSB
、 を呼び出しKeWaitForSingleObject
て待機するように見えます。10 回のうち 9 回 (文字通り - トレースには 10 個のサンプルがあります)、これは非常に迅速に返され (それぞれ 324us)、コールスタックの準備が整い、usbport.sys!USBPORT_Core_iCompleteDoneTransfer
その後に が続きHIDUSB.SYS!HumCallUsbComplete
ます。これは非常に正常に見えます。
しかし、10 分の 1 の割合で、これが戻るのにほぼ正確に 5 秒かかります。準備中のコールスタックntkrnlmp.exe!KiTimerExpiration
には、関数の代わりがありHIDUSB.SYS
ます。これはすべて、HIDUSB.SYS ドライバーが 5 秒のタイムアウトで非同期的にデバイスにクエリを実行していることを示していると思いますが、失敗してこのタイムアウトに達することがあります。
この障害が特定の 1 つのデバイスに関連しているのか (私はいくつかの USB HID を持っています)、それともランダムなのかはわかりません。常に発生するとは限らないため、テストするのは困難です。繰り返しになりますが、誰かが私に提供できる情報は大歓迎ですが、DirectInput が奇妙な状況にあることを考えると、Microsoft がすぐにこれを修正するという希望はありません!
おそらく、入力の初期化を早めに非同期で開始し、ユーザー入力が発生するまでに 5 秒の遅延が発生する場合があることを受け入れる必要があるでしょう。