Неправильно ли вызывать асинхронный метод из установщика свойств в модели представления WPF? - PullRequest
0 голосов
/ 04 мая 2018

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

Неправильно ли вызывать асинхронный метод из не асинхронного установщика? Я заметил, что если асинхронный метод возвращает void, VS не жалуется, но если он возвращает Task, то Visual Studio жалуется, что вызов не ожидается. Мой код выглядит так:

public int Property1
{
    set 
    {
        _property1 = value;
        NotityPropertyChanged();
        UpdateData();
    }
}

private async void UpdateData()
{
    // show data loading message
    var data = await GetDataFromWebService();
    Property2 = data;
    // hide data loading message
}

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

ОБНОВЛЕНИЕ: в нескольких ответах и ​​комментариях предлагается использовать команды вместо обновления в ответ на изменение свойства. В моем случае я не уверен, как это можно применить, поэтому предоставляю более подробную информацию о том, как ожидается, что пользовательский интерфейс будет работать.

В пользовательском интерфейсе есть средство выбора даты (которое привязано к рассматриваемому свойству в модели представления), где пользователь выбирает дату, для которой он хочет просмотреть записи. Когда пользователь выбирает новую дату, приложение должно показывать индикатор занятости, а затем извлекать записи в фоновом режиме, чтобы избежать блокировки потока пользовательского интерфейса. Желательно, чтобы обновление запускалось при выбранной дате, не требуя, чтобы пользователь нажимал кнопку после выбора даты.

Было бы лучше связать событие SelectionChanged средства выбора даты и асинхронную команду в ViewModel или альтернативно иметь обработчик синхронизации для SelectionChanged, который напрямую вызывает метод обновления для модели представления?

Ответы [ 3 ]

0 голосов
/ 04 мая 2018

Это не самый чистый способ, как уже говорилось, но вы можете оставить его. Во-первых, это не вредно, за исключением того, что вы скрываете неожиданную долгую и дорогую операцию за быстрым заданием

MSDN говорит :

Асинхронный метод также может иметь тип возврата void. Этот тип возврата используется в основном для определения обработчиков событий, где требуется тип возврата void. Асинхронные обработчики событий часто служат отправной точкой для асинхронных программ.

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

Простым решением может быть прослушивание события PropertyChanged. Это было бы больше похоже на спасение от сеттера. Лучше сделать так, чтобы ваша ViewModel выставляла команду обновления, реализуя асинхронный интерфейс ICommand , добавляя к нему асинхронное выполнение. Затем вы будете вызывать эту AsyncCommand из вашего View при каждом изменении свойства. Вы также можете передать новое значение в качестве параметра команды в ViewModel.

0 голосов
/ 04 мая 2018

Автоматический вызов обновлений при изменении только свойства обычно является плохой идеей.
Обычно кнопка и команда - лучший план. В качестве альтернативы вы можете вызвать команду из пользовательского интерфейса, а не использовать этот установщик. И это было бы относительно просто сделать.

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

0 голосов
/ 04 мая 2018

Неправильно ли вызывать асинхронный метод из не асинхронного установщика?

Короче да. Свойства не должны запускать асинхронные фоновые операции в их установщиках.

Рекомендую прочитать пост Стивена Клири в блоге и статью на MSDN на эту тему:

Асинхронное программирование: шаблоны для асинхронных приложений MVVM: привязка данных: https://msdn.microsoft.com/en-us/magazine/dn605875.aspx

Асинхронный ООП 3: Свойства: https://blog.stephencleary.com/2013/01/async-oop-3-properties.html

Вы также можете захотеть взглянуть на функциональную инфраструктуру MVVM, такую ​​как ReactiveUI , которая обрабатывает этот сценарий путем преобразования свойств в наблюдаемые потоки значений, на которые вы можете подписаться: https://reactiveui.net/docs/getting-started/

...