0

これに対する決定的な答えを調査するためにしばらく時間を費やしましたが、信頼できる情報源を見つけることができませんでした.

私のシナリオはかなり簡単です。タイマーからの定期的なイベントを処理するメッセージ ポンプ セットアップを含むスレッドがあります。メッセージポンプのソースは次のとおりです。

// create timer that goes off every 500 ms
UINT_PTR myTimerID = SetTimer(NULL, 0, 500, TimerCallback);

// message structure
MSG msg;

// process and handle messages for this thread
BOOL getMessageStatus;
while((getMessageStatus = GetMessage(&msg, NULL, 0, 0)) != 0)
{
    // failed get message
    if(getMessageStatus == -1)
    {
        printf("GetMessage FAILED!\n");
    }
    // process timer message
    else if(msg.message == WM_TIMER)
    {
        // invoke callback
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

TimerCallback に 500 ミリ秒以上かかる場合、タイマーはそのイベントを再度発生させます。コールバックはメッセージ ポンプと同じスレッドで実行されているため、次のタイマー メッセージがメッセージ ポンプによって処理される前に、コールバックが完了する必要があると想定しています。

あれは正しいですか?

4

2 に答える 2

2

SetTimer()メッセージベースのタイマーです。タイマーが経過すると、メッセージ キュー内に特別なフラグが設定されます。新しいメッセージのキューをポンピングするとWM_TIMER、そのフラグが設定されていて、他の優先度の高いメッセージがキューで待機していない場合、メッセージが作成されます。コードが生成されたWM_TIMERメッセージのディスパッチでビジー状態になっている間に、タイマーがバックグラウンドで経過し、フラグが再び設定され、WM_TIMER次にメッセージのキューをポンピングしたときに新しいメッセージが生成されます。そのため、コールバック内で直接またはモーダル ダイアログを介してメッセージをポンピングすることには注意してください。これは、タイマー コールバックの再帰呼び出しにつながる可能性があり、時間の経過とともにスタック オーバーフローが発生する可能性があるためです。しかし、メッセージ ポンピングがメイン スレッド ループのみにある場合は問題ありません。

于 2012-09-24T19:56:46.890 に答える
1

メッセージを処理するためのエントリ ポイントが 1 つしかない限り、一度に処理できるメッセージは 1 つだけです。すでに実行中のイベント ハンドラーでさらに多くのメッセージを処理することで問題が発生する可能性がありますが、そうしないでください。問題はありません。

于 2012-09-24T19:54:44.787 に答える