11

私のWPFアプリケーションでは、ユーザーがボタンを押して3Dモデルのスムーズな回転を開始し、ボタンを離して回転を停止します。

これを行うには、DispatcherTimerを作成します。

DispatcherTimer timer = new DispatcherTimer();
timer.Tick += new EventHandler( timer_Tick );
timer.Interval = new TimeSpan( 0, 0, 0, 0, 30 );

そして、ボタンが押されたtimer.Start()ときに電話をかけ、ボタンを離したときに電話をかけますtimer.Stop()

このtimer_Tick関数は、モデルの回転を変更します。

    void timer_Tick( object sender, EventArgs e )
    {
        spin = ( spin + 2 ) % 360;
        AxisAngleRotation3D rotation = new AxisAngleRotation3D( new Vector3D( 0, 1, 0 ), spin );
        Transform3D rotate = new RotateTransform3D( rotation );
        model2.Transform = rotate;
    }

私が気付いたのは、モデルはほとんどの部分でスムーズに回転しますが、多くの場合、フリーズして途切れ、さまざまな時間、場合によっては最大1/4秒の間一時停止します。

これをスムーズにする方法はありますか?DispatcherTimerを使用することで(たとえば、System.Timers.Timerとは対照的に)、コールバックがUIスレッドで発生することを理解しています。しかし、ラインを実行するには、UIの脅威にさらされている必要があります

        model2.Transform = rotate;

他のスレッドでタイマーコールバックを取得するさまざまな方法について読んだことがあります。しかし、最終的には、その行を呼び出すためにUIスレッドと同期する必要があるようです。Invoke()を使用して、たとえばSystem.Timers.TimerコールバックスレッドからUIスレッドにマーシャリングする場合、全体的にスムーズなアニメーションが得られますか?DispatcherTimerと同じようにUIスレッドと同期する必要があるため、そうすべきではないようです。そして、そのことについては、一定の間隔で設定するためのスキームは、UIスレッドに関して同じボートにあるようですよねmodel2.Transform

(おそらく二次的な質問として、私は最初に一時停止の原因を理解しようとしています。私が知る限り、UIスレッドが行っていることは他に重要なことは何もありません。したがって、それらの間に何が起こっているのかわかりません。一時停止します。ガベージコレクション?収集するガベージはそれほど多くないようです。また、一時停止がそれほど極端ではないようです。)

4

1 に答える 1

17

優先度を設定します。デフォルトはです。これはBackground、表示される吃音を説明している可能性があります。私Renderはあなたが望むレベルだと思いますが、実験してください。

DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Render);

それが十分にスムーズでない場合は、アニメーションとして設定してみてください。

于 2013-01-16T09:37:51.100 に答える