Вызов асинхронного метода для загрузки данных в конструктор viewmodel вызывает предупреждение

#c# #.net #wpf #asynchronous #async-await

#c# #.net #wpf #асинхронный #async-await

Вопрос:

Мое представление содержит ListView, в котором отображаются некоторые данные из Интернета, я создаю асинхронный метод для загрузки данных и вызываю метод в конструкторе моей viewmodel. У него есть предупреждающий запрос, чтобы я теперь использовал ключевое слово await.

Есть ли другое решение для асинхронной загрузки данных в конструктор?

Комментарии:

1. Вы должны показать свой код, а также включить фактическое предупреждение в свой вопрос.

2. Для решения этой проблемы прочитайте «Шаблоны для асинхронных приложений MVVM: привязка данных» Стивена Клири и «Асинхронный ООП 2: конструкторы» Стивена Клири.

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

Ответ №1:

Есть пара шаблонов, которые могут быть применены, все упомянутые в сообщении Стефана Клири.

Однако позвольте мне предложить кое-что немного другое:

Поскольку вы находитесь в приложении WPF, я бы использовал FrameworkElement.Loaded событие и привязал его к ICommand вашей ViewModel. Ограниченной командой была бы команда, Awaitable DelegateCommand которую можно ожидать. Я также воспользуюсь System.Windows.Interactivity.InvokeCommandAction

Просмотр XAML:

 <Grid>
 <interactivity:Interaction.Triggers>
     <interactivity:EventTrigger EventName="Loaded">
         <interactivity:InvokeCommandAction Command="{Binding MyCommand}"/>
     </interactivity:EventTrigger>
 </interactivity:Interaction.Triggers>
</Grid>
  

ViewModel:

 public class ViewModel
{
    public ICommand MyCommand { get; set; }

    public ViewModel()
    {
        MyCommand = new AwaitableDelegateCommand(LoadDataAsync);
    }

    public async Task LoadDataAsync()
    {
        //await the loading of the listview here
    }
}
  

Ответ №2:

Лично я бы делегировал загрузку данных методу, например, Task LoadDataAsync(…) … однако, если вы присвоите результат асинхронного метода полю, тогда предупреждение должно исчезнуть. Если вы вызываете Wait(), то сомнительно, следует ли вам вообще вызывать асинхронный метод.

Смотрите http://blog.stephencleary.com/2013/01/async-oop-2-constructors.html для шаблона асинхронной инициализации, который может вас заинтересовать.

Комментарии:

1. О боже! Спасибо за публикацию заводского шаблона Клири. Я преследовал свой хвост, почему я не могу реорганизовать async в ViewModel. Теперь я могу. Отлично!!