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

M K*_*atz 8 c# wpf smooth timer dispatchertimer

在我的WPF应用程序中,用户按下按钮以启动平滑旋转的3D模型,然后让按钮停止旋转.

为此,我创建了一个DispatcherTimer:

DispatcherTimer timer = new DispatcherTimer();
timer.Tick += new EventHandler( timer_Tick );
timer.Interval = new TimeSpan( 0, 0, 0, 0, 30 );
Run Code Online (Sandbox Code Playgroud)

当按下按钮时,我打电话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;
    }
Run Code Online (Sandbox Code Playgroud)

我注意到的是,模型在大多数情况下平滑旋转,但经常冻结和口吃,暂停不同的持续时间,有时高达1/4秒.

有没有办法让这更顺畅?我理解通过使用DispatcherTimer(而不是System.Timers.Timer),回调发生在UI线程上.但是为了运行这条线,我必须处于UI威胁之中

        model2.Transform = rotate;
Run Code Online (Sandbox Code Playgroud)

我已经阅读了有关在其他线程上获取计时器回调的各种方法.但似乎最终我必须与UI线程同步才能调用该行.如果我使用Invoke()从System.Timers.Timer回调线程编组到UI线程,那么会给整体更平滑的动画吗?它似乎不应该,因为它必须与UI线程同步,就像DispatcherTimer可能做的那样.对于这个问题,似乎任何设置model2.Transform定期间隔的方案都与UI线程在同一条船上,不是吗?

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

Hen*_*man 13

设置优先级.默认值是Background,这可能解释了您看到的口吃.我认为Render是你想要的水平,但做实验.

DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Render);
Run Code Online (Sandbox Code Playgroud)

如果这不够平滑,您可以尝试将其设置为动画.

  • 有用.谢谢你的简单解决方案.我仍然想了解DispatcherTimer优先级较低时暂停期间发生的情况.该框架刚刚决定让DispatcherTimer饿死一段时间?为什么?忙什么呢? (2认同)