Вызов метода 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">