Приложение WPF зависает при получении данных и обновлении DataGrids - PullRequest
0 голосов
/ 07 апреля 2020

У меня есть набор функций, заполняющих различные DataGrids объектами EF, подобными этому:

var items = db.Items.AsNoTracking().Where(n => n.CategoryId == categoryId);
var grid = grdItems as DataGrid;
grid.ItemsSource = items;

Проблема, с которой я столкнулся, заключается в том, что окно зависает, т.е. не может щелкнуть или сделать что-либо, пока не закончится приведенный выше код. После завершения сетки заполняются правильно, поэтому никаких проблем нет, но в течение коротких нескольких секунд он, похоже, потерпел крах.

Я хотел добавить простое окно / диалоговое окно с типом загрузки, чтобы по крайней мере пользовательский интерфейс отображал что-то для пользователя, а не то, что он вылетел. Моя проблема в том, что при добавлении frm.Show, frm.Hide до / после этого кода выше или при попытке использовать оверлей UserControl он никогда не отображается, потому что я ожидаю, что поток занят.

Я не использовал WPF очень долго и исторически я использовал формы, где в подобных случаях я использовал DoEvents, но, насколько я понимаю, это скорее вредно, чем полезно, поэтому я прошу Лучший способ обновить пользовательский интерфейс с загрузкой оверлея, пожалуйста. В частности, в случае заполнения DataGrid, и я ожидаю, что любые обрабатываемые конвертеры / Vaildators вносят вклад в занятость потока.

Ответы [ 2 ]

1 голос
/ 07 апреля 2020

Вы должны либо извлекать элементы асинхронно:

progressBar.Visibility = Visibility.Visible;
var items = await db.Items.AsNoTracking().Where(n => n.CategoryId == categoryId)
    .ToListAsync();
progressBar.Visibility = Visibility.Collapsed;

... или делать это синхронно в фоновом потоке:

var items = await Task.Run(() => db.Items.AsNoTracking()
    .Where(n => n.CategoryId == categoryId)
    .ToList());

См. Асинхронное программирование с асинхронной c и ждите для получения дополнительной информации об асинхронном программировании в C#.

0 голосов
/ 07 апреля 2020

Доступ к данным действительно должен выполняться с использованием асинхронных вызовов вне интерфейса пользователя.

Обычно это делается с помощью реализации Command (вызываемой из пользовательского интерфейса), которая, в свою очередь, запускает async Task.

. Этот Task можно использовать для установки логического флага. чтобы показать, что система занята, что, в свою очередь, может указывать пользователю на это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...