如何使 WPF 中的 DispatcherTimer 事件更流畅?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14354561/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to make DispatcherTimer events smoother in WPF?
提问by M Katz
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.
在我的 WPF 应用程序中,用户按下按钮开始平滑旋转 3D 模型,然后松开按钮停止旋转。
To do this, I create a DispatcherTimer:
为此,我创建了一个 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().
当按下按钮时我打电话timer.Start(),当按钮松开时我打电话timer.Stop()。
The timer_Tickfunction changes the rotation of the model:
该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;
}
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.
我注意到模型在大多数情况下旋转平稳,但经常冻结和卡顿,暂停不同的持续时间,有时长达 1/4 秒。
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
有没有办法让它更顺畅?我知道通过使用 DispatcherTimer(而不是 System.Timers.Timer)回调发生在 UI 线程上。但我有必要在 UI 威胁上运行这条线
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 anyscheme for setting model2.Transformon a regular interval would be in the same boat with respect to the UI thread, no?
我已经阅读了在其他线程上获取计时器回调的各种方法。但似乎最终我必须与 UI 线程同步才能调用该行。如果我使用 Invoke() 将 System.Timers.Timer 回调线程编组到 UI 线程,是否会提供整体更流畅的动画?似乎不应该,因为它必须像 DispatcherTimer 一样与 UI 线程同步。就此而言,似乎任何model2.Transform定期设置的方案都与 UI 线程处于同一条船上,不是吗?
(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.)
(作为一个可能的次要问题,我首先试图了解是什么导致了暂停。据我所知,UI 线程没有做其他重要的事情。所以我不明白在这些期间发生了什么暂停。垃圾收集?似乎不应该收集太多垃圾,而且暂停似乎也不会如此极端。)
回答by Henk Holterman
Set a priority. The default is Background, that might explain the stuttering you see. I think Renderis the level you want but do experiment.
设置优先级。默认值为Background,这可能解释了您看到的口吃。我认为Render是你想要的水平,但做实验。
DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Render);
If that isn't smooth enough you could try setting it up as an Animation.
如果这还不够流畅,您可以尝试将其设置为动画。

