dポイントプレゼントキャンペーン実施中!

SetTimerとの比較も兼ねてtimeSetEvent関連を調べていたのですが

CALLBACKの外部で
timeSetEventの戻り値を保存しておき、必要な時にそのIDを基に
timeKillEventするサンプルは簡単に見つかったのですが
timeKillEventは内部で使ってもいいのでしょうか?

なるべく端折って書くとたとえば

timeBeginPeriod( 8 );
timeSetEvent( 40, 8, TimerProc, 0, TIME_PERIODIC );

とでもした場合に
timeSetEventの重ねがけをしない(するならもうちょっと変更)
という前提で

void CALLBACK TimerProc( UINT ID, UINT, DWORD User, DWORD , DWORD ){
static int d(11);

if ( !--d ){
timeKillEvent(ID);
timeEndPeriod(8);
}
}

的なことをしても問題ないのでしょうか?
(出力やtimeGetTimeなどの関数を付加して実験してみた結果だけだと、問題なく動いているように見えるのですが、実はすぐには分からないような問題が内部的に発生してる可能性はありますか?)

A 回答 (1件)

多分大丈夫でしょう。


timeSetEventのコールバックについての情報ではありませんが、同じマルチメディア系のMidiOutProcコールバック関数について
> アプリケーションでは、EnterCriticalSection、LeaveCriticalSection、
> midiOutLongMsg、midiOutShortMsg, OutputDebugString、PostMessage、
> PostThreadMessage、SetEvent、timeGetSystemTime、timeGetTime、
> timeKillEvent および timeSetEvent を除き、コールバック関数内から
> システム定義関数を呼び出さないようにします。ほかのウェーブ関数を
> 呼び出すと、デッドロックの原因となります。
という解説があります。(MSDN)
逆にいうと記載のtimeKillEvent等は大丈夫ということでしょう。
ただしtimeKillEventを実行したら二度とこのコールバック関数が呼ばれないということは保証できないようです。既にイベントがキューイングされている可能性があるのでそれについては対処しましょう。
    • good
    • 0
この回答へのお礼

お、ほんとだ
MidiOutProcの解説にそういう文章がありますね♪
ありがとうございます!

別の実験で
上記のように使い捨て的な判定するのではなくしておいて
別個に配列にIDを確保しておくようにして、timeSetEventをたくさん連続で呼んだり
timeSetEvent→timeKillEvent→timeSetEvent→timeKillEvent

といったことも試してみて問題はないようなので

(ただ、連続で呼ぶほうはなぜか同じコールバック関数に対して一定の回数以上はできない・・・?というような現象が出ましたが、そんなに何回も呼ぶような設計はそもそもCPUへの影響とかタイミングのとりやすさも含めてあまりやらないで済むほうがいいと思うので)

おそらく、むしろ単発で好きな時に走らせて、用がすんだらすぐに止めるようにしつつ、何度でも呼べることを前提にした設計の方が汎用性があっていいかもしれませんね。
(てかそういうことならスレッドのほうが意味的にあってるかもしれませんw)

作戦はいろいろ考えられますが、いずれにせよありがとうございます。

お礼日時:2010/03/04 12:26

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!