UWP ProgressRing отображается с большой задержкой при загрузке данных в фоновом режиме - PullRequest
1 голос
/ 15 марта 2019

Я использую UWP GridView с DataTemplateSelector, чтобы показать данные за разные недели. Когда я меняю неделю, я хочу показать загрузчик при загрузке данных. Я использую MvvmLight для привязки ViewModels и при изменении данных удаляю и добавляю элементы в источник GridView. Проблема в том, что когда я изменяю свойство IsActive на true, прежде чем запустить метод UpdateGrid, загрузчик не активен и на экране возникает задержка. Если загрузка данных (UpdateGrid метод) занимает более одной секунды, загрузчик виден, так что для меня это означает, что логика там в порядке, но проблема может быть в генерировании графических элементов на экране и производительности?

Я пытался сделать мой UpdateGrid метод асинхронным и синхронизированным (внутри нет вызова API, поэтому возможна синхронизация). Метод вызывается в классе ViewModel:

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

1 Ответ

1 голос
/ 15 марта 2019

Возможно, вы неправильно понимаете, как работает async/await. Когда вы помечаете метод async и он не содержит real await (что означает отсутствие операции ввода-вывода или операции, которая фактически выполняется в другом потоке), весь метод по существу будет выполняться синхронно. Это верно в вашем случае, так как вы упомянули, что внутри UpdateGrid нет никакой асинхронной работы, поэтому код будет работать так, как если бы в действительности не было await.

Поток пользовательского интерфейса будет занят все время с момента установки SyncLoadingImageVisible на true до момента, когда вы установите его обратно на false - в течение этого времени поток пользовательского интерфейса на 100% посвящен выполнению вашего кода поэтому пользователь не увидит никаких изменений пользовательского интерфейса. Это вызывает поведение, которое вы наблюдаете - что существует задержка, поскольку поток пользовательского интерфейса не имеет возможности обновить пользовательский интерфейс, пока не завершится выполнение метода UpdateGrid.

Чтобы решить эту проблему должным образом, вам придется перенести интенсивные, не связанные с пользовательским интерфейсом задачи в методе UpdateGrid в другой поток, используя ожидаемый Task.Run, и только пользовательский интерфейс, который действительно работает с пользовательским интерфейсом приложения, должен затем выполняться в пользовательском интерфейсе. нить. Таким образом вы освободите поток пользовательского интерфейса, чтобы иметь возможность отображать прогресс для пользователя, пока выполнение выполняется в фоновом режиме.

...