how to make DispatcherTimer events smoother in WPF?

谁说胖子不能爱 提交于 2020-01-11 02:04:11

问题


In my WPF application, the user presses a button to start a 3D model rotating smoothly, and lets up on the button to stop the rotation.

To do this, I create a DispatcherTimer:

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

And when the button is pressed I call timer.Start() and when the button is let up I call timer.Stop().

The timer_Tick function changes the rotation of the model:

    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;
    }

What I notice is that the model spins smoothly for the most part, but often freezes and stutters, pausing for various durations, sometimes up to like 1/4 second.

Is there a way to make this smoother? I understand that by using DispatcherTimer (as opposed to, say, System.Timers.Timer) the callbacks happen on the UI thread. But it's necessary for me to be on the UI threat in order to run the line

        model2.Transform = rotate;

I have read about various ways to get a timer callback on some other thread. But it seems like in the end I have to synchronize with the UI thread to call that line. If I use Invoke() to marshal from, say, the System.Timers.Timer callback thread to the UI thread, will that give an overall smoother animation? It seems like it shouldn't, since it's having to synchronize with the UI thread just like DispatcherTimer presumably does. And for that matter it seems like any scheme for setting model2.Transform on a regular interval would be in the same boat with respect to the UI thread, no?

(As a perhaps secondary question, I'm trying to understand what's causing the pauses in the first place. As far as I can know, there's nothing else significant that the UI thread is doing. So I don't understand what's happening during those pauses. Garbage collection? It doesn't seem like there should be much garbage to collect, and it doesn't seem like the pause would be so extreme.)


回答1:


Set a priority. The default is Background, that might explain the stuttering you see. I think Render is the level you want but do experiment.

DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Render);

If that isn't smooth enough you could try setting it up as an Animation.



来源:https://stackoverflow.com/questions/14354561/how-to-make-dispatchertimer-events-smoother-in-wpf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!