WPF 鼠标在控件上晃动,CPU占用高,界面不刷新问题
首先,在MVVM模式下,我们刷新界面的方式工作通过属性绑定转移到更新绑定数据源。此时,我们通常会使用子线程去执行一些查询等耗时任务,执行完成之后,直接更新数据源。或者开一个定时器(System.Threading.Timer)去实时更新我们的绑定数据源。
一般情况下,我们的界面更新是很正常的。
但是,当我们更新的数据源很多,更新频率很快时。晃动我们鼠标(在控件面板上移动)时,有时会发现一个有趣却又很苦逼的现象——鼠标晃动导致界面更新卡住了。
我最开始遇到这个问题时,也是百度一顿乱搜。问问群里大佬。无果。
开始猜想与试验…
经过多种试验发现:
如果这个更新数据源的方式通过主线程调度(System.Windows.Threading.Dispatcher.CurrentDispatcher或者控件的Dispatcher)Invoke调用时,界面刷新不受鼠标移动影响
解决方案:
// 处理任务的子线程
Task.Run(() =>
{
while (true)
{
// 获取数据,随便模拟的
int data = new Random().Next(100);
// 更新绑定数据源,使用主线程的调度器来进行调用
System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke(() =>
{
Base.ServiceProvider.Get<MainViewModel>().CurrentTime = data.ToString();
});
}
});
最后,谈谈个人理解:
由于子线程去更新数据,界面刷新需要在主线程空闲的时候才会去更新数据。当鼠标在移动时,主线程会开辟部分资源去等待响应鼠标事件(这块资源挺大,因为CPU一下从1涨到了8左右),当子线程刷新数据源过多时,导致CPU属性通知资源不足,从而界面卡死不更新。
积跬步以至千里:) (:一阵没来由的风