6

waveOutOpenメソッドとwaveOutWriteAPIメソッドを使用して小さなチャンクを連続して再生することで長いWAVファイルを再生するコードエンジンがあります。ファイルの再生中にUIを更新するために、各バッファーの再生が完了するとコールバック関数から、フォームのメソッドを呼び出す別のスレッドを呼び出します(コールバック関数内で実行することはできるだけ少なくしたいため)。

EventHandlerフォームには、 UI要素を新しい情報で更新するメソッドを処理するクラスレベルが含まれています。waveOutWriteコールバック関数から呼び出されるformメソッドでは、次のようにInvokeメソッドを使用します。

if (_updatedisplay == null)
{
    // UpdateDisplay contains code to set control properties on the form
    _updatedisplay = new EventHandler(UpdateDisplay);
}
Invoke(_updatedisplay);

すべてが機能しますが、UI要素の更新に顕著な遅延または遅延があるように見えます。UpdateDisplayメソッドを使用してアニメーションを駆動しているため、これは簡単にわかります。そのため、遅延は「一時的な中断」として表示され、スプライトは予想される位置にジャンプする前に一瞬フリーズします。

このようなクロススレッド通信には、長い(おそらく10〜15ミリ秒)遅延が発生する可能性がありますか?もしそうなら、このようなものを処理するためのより良い方法は何ですか?

更新:ちなみに、それがここの原因かどうかは確かにわかりませInvoke。もう1つの可能性は、オーディオのチャンクの再生が終了してからコールバック関数が実際に呼び出されるまでの遅延です。

更新2itowlsonの提案に従って、メソッド呼び出しSystem.Diagnostics.Stopwatch間のラグをベンチマークするためにを使用しました。Invoke1156回の測定のうち、0msで1146、1msで8、2msで2を取得しました。Invokeここでの私の犯人ではないと言っても差し支えないと思います。

4

1 に答える 1

3

はい、任意の長い遅延が発生する可能性があります。Invoke は、Windows メッセージをターゲット コントロールに送信することによって機能するため、ターゲット スレッドがメッセージを送り出すときにのみ処理されます。スレッドが既にメッセージを処理しており、その処理に時間がかかる場合、スレッドが次のメッセージをポンプして Invoke を処理するまでにかなりの遅延が生じる可能性があります。

より良い方法は、BeginInvoke を呼び出すことです。これは、UI スレッドがメッセージを処理する際の遅延の可能性を回避するものではありませんが、UI スレッドがメッセージを送り出すのを待っている間に呼び出しスレッドがブロックされるのを防ぎます。ただし、これは、アニメーションでグリッチを引き起こしている UI スレッドのビジーネスのように聞こえるシナリオでは役に立たない場合があります。

あなたの更新に応じて更新する: ここで言っているのは、任意に長い遅延が発生する可能性あるということだけであり、顕著な遅延があるということでも、これが間違いなく遅延の原因であるということでもありません。10 ~ 15 ミリ秒という時間は、UI スレッドで非常に集中的なことが起こっていない限り、アプリケーションがメッセージ処理に費やす時間が異常に長いように思われるため、別の原因を検討するのが賢明です。

于 2010-02-20T21:51:26.070 に答える