Настольное приложение клиент / сервер с использованием C #, WCF, WPF . Поскольку практически каждое действие требует обращения к серверу (список / создание / сохранение / удаление и т. Д.), Каждое действие может заморозить весь пользовательский интерфейс. Вот пример наивной реализации с вызовом service.GetAll ()
, который может занять «долгое» время (более нескольких сотен миллисекунд):
private void btnRefresh_Click(object sender, RoutedEventArgs e)
{
vm.Users.Clear();
foreach (var user in service.GetAllUsers())
vm.Users.Add(user);
}
(Кроме того, я бы хотел знать, почему Список имеет AddRange
, а ObservableCollection не имеет.)
BackgroundWorker
на помощь:
private void btnRefresh_Click(object sender, RoutedEventArgs e)
{
var worker = new BackgroundWorker();
worker.DoWork += (s, e) =>
{
Dispatcher.BeginInvoke((Action)delegate() { btnRefresh.IsEnabled = false; });
e.Result = service.GetAllUsers();
};
worker.RunWorkerCompleted += (s, e) =>
{
vm.Users.Clear();
foreach (var user in (List)e.Result)
vm.Users.Add(user);
Dispatcher.BeginInvoke((Action)delegate() { btnRefresh.IsEnabled = true; });
};
worker.RunWorkerAsync();
}
(Кроме того, код выше имеет было упрощено, но в этом суть. )
Код, использующий BackgroundWorker
, работает именно так, как я хочу. Приложение всегда реагирует на запросы, а кнопка неактивна на время разговора. Однако это означает добавление 15 строк к каждому возможному действию, которое может совершить пользователь.
Скажите, что это не так.