11

在我的 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 可能所做的那样。就此而言,对于 UI 线程而言,任何model2.Transform定期设置的方案似乎都在同一条船上,不是吗?

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

4

1 回答 1

17

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

DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Render);

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

于 2013-01-16T09:37:51.100 回答