How to make DispatcherTimer events smoother in WPF?

In my WPF application, the user presses a button to start the 3D model, spinning smoothly, and releases the button to stop 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 released, 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 flows smoothly for the most part, but often freezes and stutters, stopping for different durations, sometimes up to 1/4 of a second.

Is there any way to make this smooth? I understand that with DispatcherTimer (unlike, say, System.Timers.Timer) callbacks occur in the user interface thread. But I need me to be threatened by the UI to run the line

  model2.Transform = rotate; 

I read about different ways to get a timer callback in another thread. But it seems that in the end I need to synchronize with the UI thread to invoke this line. If I use Invoke () to marshal, say, the System.Timers.Timer callback thread for the UI thread, will this give an overall smoother animation? It seems that this should not be, since it should be synchronized with the user interface stream, such as DispatcherTimer. And in this regard, it seems that any installation scheme for model2.Transform at a regular interval will be in the same boat with respect to the user interface thread, no?

(As perhaps a minor issue, I am trying to understand what causes the pauses in the first place. As far as I know, there is nothing significant that the user interface thread does. Therefore, I do not understand what happens during these pauses. Garbage collection? It seems not there should be a lot of garbage to collect, and it doesn't look like the pause will be so extreme.)

+7
source share
1 answer

Set priority. The default is Background , which can explain the stutter you see. I think Render is the level you want, but experimenting.

 DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Render); 

If it's not smooth enough, you can try setting it up as an animation.

+11
source

All Articles