我正在尝试在后台线程中托管一个控件,这样即使UI线程被阻止,它也可以以60 FPS的恒定速度显示动画.这在Windows 8.1中完美运行,但自从升级到Windows 10后,它现在失败了.
我从托管控件的后台线程挂钩CompositionTarget.Rendering事件,以便动画可以与监视器刷新同步.但似乎只要主UI线程中的某些内容也挂钩到Rendering事件,只要主UI线程中托管的可视化更改,就会跳过框架.
我可以在视觉上看到跳过的帧,并且根据RenderingEventArgs类中公开的RenderTime,这确认正在跳过帧,因为每当帧跳过发生时,自上一帧以来的时间增量大约为33ms而不是16ms.
可以通过在UI线程中挂钩CompositionTarget.Rendering事件并在事件处理程序中执行任何操作,或者通过启动故事板动画来引发跳过,我猜测是因为故事板动画挂钩了CompositionTarget.Rendering事件以实现平滑动画.
这是一个简单的示例项目,它演示了这个问题:
我已经在Windows 8.1和Windows 10上在几台机器上进行了测试,在任何情况下,无论如何,Windows 8.1都能以60 FPS的"自有线程"控制完美运行.在Windows 10中,"显示抖动1"将帧速率降低到恒定的30 FPS,"显示抖动2"导致帧速率在30到60 FPS之间不规律地切换,平均大约45-50.
在Windows 8.1和Windows 10中,按下"阻止UI线程"按钮可在单独的线程控制中获得平滑的60 FPS.
一个解决方案是让动画在UI线程中运行并从该线程中删除所有阻塞代码,不幸的是,这不是一个简单的任务,因为我正在处理的应用程序很复杂,并且UI可以阻止很多地方超过几毫秒,这可能会导致动画中的抖动.