使用 MVVM Light 在 WP Universal App 上异步加载数据
Loading data asynchronously on WP Universal App using MVVM Light
我正在使用 MVVM Light 开发 Windows Phone 通用应用程序(我是 MVVM 模式的新手)。我的问题是让它像那样工作:
- 应用程序启动(或用户导航到不同的视图),
- 然后我们看到基本的UI,
- 然后我们等待数据加载,同时应用程序保持响应。
到目前为止,我已经测试了许多不同的方法,例如:
- implementing
NotifyTaskCompletion<T>
- implementing async command
- call an async void from viewmodel constructor
- loading data in command called by "page loaded" event
并且在每种情况下,我的应用程序都显示启动画面(或者在导航到另一个页面之前被阻止),除非数据已加载。 方法 return 数据正确, 视图显示得很好。
所以我的问题是,在 Universal App 中异步加载数据的正确方法是什么?非常感谢您的帮助。
这是我的代码现在的样子:
MainViewModel.cs
public MainViewModel()
{
this._navigationService = ServiceLocator.Current.GetInstance<INavigationService>();
_newsService = ServiceLocator.Current.GetInstance<INewsService>();
LoadMainPageCommand =
new RelayCommand(async() => await LoadMainPageData());
}
public RelayCommand LoadMainPageCommand { get; set; }
private async Task LoadMainPageData()
{
// to make it work a bit longer
for (int i = Int32.MaxValue; i > 20000; i--) ;
NewsCategories= await _newsService.GetNewsCategoriesAsync();
RaisePropertyChanged("NewsCategories");
}
HubPage.xaml
<Page
x:Class="xxx.HubPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:xxx"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:data="using:xxx.Data"
mc:Ignorable="d">
<i:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Loaded">
<core:InvokeCommandAction Command="{Binding LoadMainPageCommand}"/>
</core:EventTriggerBehavior>
</i:Interaction.Behaviors>
...
INewsService.cs
public interface INewsService
{
Task<ObservableCollection<NewsCategory>> GetNewsCategoriesAsync();
}
您的问题出在您的 "test" 代码中:
private async Task LoadMainPageData()
{
// to make it work a bit longer
for (int i = Int32.MaxValue; i > 20000; i--) ;
NewsCategories= await _newsService.GetNewsCategoriesAsync();
RaisePropertyChanged("NewsCategories");
}
这是一个具有异步签名的方法,它正在执行同步工作。如果你想坚持延迟,那就异步做:
private async Task LoadMainPageData()
{
// to make it work a bit longer
await Task.Delay(TimeSpan.FromSeconds(3));
NewsCategories= await _newsService.GetNewsCategoriesAsync();
RaisePropertyChanged("NewsCategories");
}
那么任何一种方法都应该有效。
我正在使用 MVVM Light 开发 Windows Phone 通用应用程序(我是 MVVM 模式的新手)。我的问题是让它像那样工作:
- 应用程序启动(或用户导航到不同的视图),
- 然后我们看到基本的UI,
- 然后我们等待数据加载,同时应用程序保持响应。
到目前为止,我已经测试了许多不同的方法,例如:
- implementing
NotifyTaskCompletion<T>
- implementing async command
- call an async void from viewmodel constructor
- loading data in command called by "page loaded" event
并且在每种情况下,我的应用程序都显示启动画面(或者在导航到另一个页面之前被阻止),除非数据已加载。 方法 return 数据正确, 视图显示得很好。
所以我的问题是,在 Universal App 中异步加载数据的正确方法是什么?非常感谢您的帮助。
这是我的代码现在的样子:
MainViewModel.cs
public MainViewModel()
{
this._navigationService = ServiceLocator.Current.GetInstance<INavigationService>();
_newsService = ServiceLocator.Current.GetInstance<INewsService>();
LoadMainPageCommand =
new RelayCommand(async() => await LoadMainPageData());
}
public RelayCommand LoadMainPageCommand { get; set; }
private async Task LoadMainPageData()
{
// to make it work a bit longer
for (int i = Int32.MaxValue; i > 20000; i--) ;
NewsCategories= await _newsService.GetNewsCategoriesAsync();
RaisePropertyChanged("NewsCategories");
}
HubPage.xaml
<Page
x:Class="xxx.HubPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:xxx"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:data="using:xxx.Data"
mc:Ignorable="d">
<i:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Loaded">
<core:InvokeCommandAction Command="{Binding LoadMainPageCommand}"/>
</core:EventTriggerBehavior>
</i:Interaction.Behaviors>
...
INewsService.cs
public interface INewsService
{
Task<ObservableCollection<NewsCategory>> GetNewsCategoriesAsync();
}
您的问题出在您的 "test" 代码中:
private async Task LoadMainPageData()
{
// to make it work a bit longer
for (int i = Int32.MaxValue; i > 20000; i--) ;
NewsCategories= await _newsService.GetNewsCategoriesAsync();
RaisePropertyChanged("NewsCategories");
}
这是一个具有异步签名的方法,它正在执行同步工作。如果你想坚持延迟,那就异步做:
private async Task LoadMainPageData()
{
// to make it work a bit longer
await Task.Delay(TimeSpan.FromSeconds(3));
NewsCategories= await _newsService.GetNewsCategoriesAsync();
RaisePropertyChanged("NewsCategories");
}
那么任何一种方法都应该有效。