Является ли BackgroundWorker единственным способом сохранить работоспособность приложения WCF / WPF?

Настольное приложение клиент / сервер с использованием 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 строк к каждому возможному действию, которое может совершить пользователь.

Скажите, что это не так.

6
задан epalm 16 March 2011 в 14:56
поделиться