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

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

Любое другое решение для загрузки данных асинхронно в конструкторе?

Ответ 1

Есть несколько паттернов, которые могут быть применены, все упомянутые в сообщении Stephan Cleary.

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

Поскольку вы находитесь в приложении 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

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

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

Ответ 3

Не используйте конструктор, чтобы сделать это. Вы можете использовать событие Window Loaded, чтобы сделать это.

Это маленький пример:

public YourWindow()
{
    InitializeComponent();
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    // Your code here ...
    // If you want use async, use the keyword async in the event method.
    // private async void Window_Loaded(object sender, RoutedEventArgs e)
}

Не забудьте добавить событие в XAML:

<Title="YourWindow" ... Loaded="Window_Loaded">