UWP ProgressRing 在后台加载数据期间显示有很大延迟

UWP ProgressRing is shown with big lag during data loading in background

我使用 UWP GridViewDataTemplateSelector 来显示不同周的数据。当我更改星期时,我想在加载数据时显示加载程序。我将 MvvmLight 用于 ViewModels 绑定,当我更改数据时,我正在删除元素并将元素添加到 GridView 源。问题是,当我在 运行 UpdateGrid 方法之前将 IsActive 属性 更改为 true 时,加载程序未激活并且屏幕上出现滞后。如果数据加载(UpdateGrid 方法)花费的时间超过一秒,则加载器可见,所以对我来说这意味着逻辑没问题,但问题可能在于在屏幕上生成图形元素和性能?

我试图让我的 UpdateGrid 方法异步和同步(内部没有 api 调用,所以可以同步)。该方法在 ViewModel class:

中调用
DispatcherHelper.CheckBeginInvokeOnUI(async () =>
     {
        SyncLoadingImageVisible = true;
        await UpdateGrid();
        SyncLoadingImageVisible = false;
     });

您可能误解了 async/await 的工作方式。当你标记一个方法 async ans 它不包含 real await (意味着没有 I/O 绑定操作或实际发生在另一个线程上的操作),整个方法基本上 运行 同步。在您的情况下也是如此,正如您提到的 UpdateGrid 内部没有实际的异步工作,因此代码将像真的没有 await 一样工作。

从您将 SyncLoadingImageVisible 设置为 true 到您将其设置回 false 的那一刻,UI 线程将一直处于忙碌状态 - 在那时 UI 线程 100% 专用于执行您的代码,因此用户不会看到任何 UI 更改。这会导致您看到的行为 - 由于 UI 线程在 UpdateGrid 方法完成执行之前没有机会更新 UI,因此存在延迟。

要正确解决此问题,您必须使用等待 Task.RunUpdateGrid 方法中的性能密集型非 UI 任务卸载到另一个线程,并且只有真正有效的代码然后应用程序的 UI 应该在 UI 线程上执行。这样,您将释放 UI 线程,以便能够在后台执行 运行 时向用户显示进度。