2

Windows フォームを使用して小さな OpenGL アプリケーションをプログラミングしているときに、プロファイラーを使用していて、かなり不安定だと思われるものを発見しました。

System::Windows::Forms::Timerを使用して、マウスのアイドリングとその他のユーザー入力の組み合わせを検出しています。ティック機能は便利ですが、タイマーを「リセット」したい場合があります。これを直接行うことはできませんが、次のようにすることで正しい効果が得られます。

this->someTimer->Stop();
this->someTimer->Start();

タイマー間隔は 50ms です。ここでの「リセット」コードは、30 ミリ秒ごとに実行されることがあります。驚いたことに、これは非常に負担のかかる作業です。私のプログラム実行の 30% は、多くの場合、この 2 行で行われます。そして、これらの 2 つの行を頻繁に呼び出しているわけではありません。特定の不自然な状況では、このコードは例と同じくらい頻繁に呼び出されますが、それ以上は呼び出されOpenGLSwapBuffers()ません。これは、これら 2 行のコストがレンダリング ループ全体の約半分であることを意味していると解釈します。

現在、回避策を使用していますが、タイマー メソッドはもう少しエレガントです。私は非常に興味があります.なぜこれらの2行は計算コストが高いのですか? 私は何が欠けていますか?タイマーをリセットするより良い方法はありますか?

4

1 に答える 1

3

Start() および Stop() を呼び出すと、内部の「有効な」フラグが設定されます。このフラグは、設定 (Start の場合) または設定解除 (Stop の場合) されるたびに、次の作業を実行します。

public virtual void set_Enabled(bool value)
{
    lock (this.syncObj)
    {
        if (this.enabled != value)
        {
            this.enabled = value;
            if (!base.DesignMode)
            {
                if (value)
                {
                    if (this.timerWindow == null)
                    {
                        this.timerWindow = new TimerNativeWindow(this);
                    }
                    this.timerRoot = GCHandle.Alloc(this);
                    this.timerWindow.StartTimer(this.interval);
                }
                else
                {
                    if (this.timerWindow != null)
                    {
                        this.timerWindow.StopTimer();
                    }
                    if (this.timerRoot.IsAllocated)
                    {
                        this.timerRoot.Free();
                    }
                }
            }
        }
    }
}

ご覧のとおり、ハンドルの割り当てや管理など、単に内部フラグを設定する以上の作業が必要です。これは、表示されている問題の費用である可能性があります。

問題の可能な解決策として、.NET Framework には 3 つのタイマーの実装があることに注意してください。

  • System.Timers.Timer
  • System.Threading.Timer
  • System.Windows.Forms.Timer

System.Timers.Timer と System.Threading.Timer の実装は、タイマー機能の軽量実装であり、これらの軽量実装の 1 つがよりパフォーマンスが高く、プロジェクトの要件を満たすかどうかを調査する必要があります。実装間の機能の違いについては、Mark Michaelis のこのブログ投稿を参照してください。

于 2009-11-03T14:48:30.260 に答える