如何在WPF中使DispatcherTimer事件更顺畅?

时间:2013-01-16 09:02:45

标签: c# wpf timer smooth dispatchertimer

在我的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线程,那么会给整体更平滑的动画吗?它似乎不应该,因为它必须与UI线程同步,就像DispatcherTimer可能做的那样。就此而言,似乎任何方案在常规时间间隔内设置model2.Transform与UI线程在同一条船上,不是吗?

(作为一个可能的次要问题,我试图了解导致暂停的原因。据我所知,UI线程没有其他重要的事情。所以我不明白什么是在那些暂停期间发生。垃圾收集?看起来似乎不应该收集太多垃圾,而且似乎停顿不会那么极端。)

1 个答案:

答案 0 :(得分:13)

设置priority。默认值为Background,这可能会解释您看到的口吃。我认为Render是你想要的级别但是要做实验。

DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Render);

如果不够顺畅,可以尝试将其设置为动画。