Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
375 views
in Technique[技术] by (71.8m points)

c# - how to make DispatcherTimer events smoother in WPF?

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.)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...