我正在使用便携版mvvmlight开发一款win phone 8应用程序。
在创建ViewModel时,我必须使用Azure移动服务Sdk调用从Azure移动服务读取数据的服务。
Sdk apis使用async / await来完成工作,我不能在ViewModel或Service costructor中进行异步调用。
代码是这样的:
public ListaArtiModel(INavigate navigationService)
{
_navigationService = navigationService;
ArtiMarzialiService artiService = new ArtiMarzialiService();
List<ArteMarziale>risultato = await artiService.ListaArti();
}
,编译器告诉
错误1“await”运算符只能在异步方法中使用。考虑使用'async'修饰符标记此方法并将其返回类型更改为'Task'。
我该如何解决这个问题? 谢谢, 卢卡
答案 0 :(得分:2)
我的"task notifier" type中有一个AsyncEx library,基本上是INotifyPropertyChanged
的{{1}}包装器。您可以像这样使用它:
Task<T>
然后您的数据绑定代码可以使用public ListaArtiModel(INavigate navigationService)
{
_navigationService = navigationService;
ArtiMarzialiService artiService = new ArtiMarzialiService();
Arti = NotifyTaskCompletion.Create(LoadArti(artiService));
}
private async Task<ObservableCollection<ArtiMarziali>> LoadArti(ArtiMarzialiService artiService)
{
return new ObservableCollection<ArtiMarziali>(await artiService.ListaArti());
}
public INotifyTaskCompletion<ObservableCollection<ArtiMarziali>> Arti { get; private set; }
,Arti.Result
,Arti.IsFaulted
等。
答案 1 :(得分:1)
您应该重新设计ViewModel,使其具有用于设置ViewModel的LoadDataAsync()
或InitializeAsync()
方法
通常,类构造函数应尽可能简单,并且应避免在构造函数中执行任何长时间运行或可能异常的工作
答案 2 :(得分:1)
我认为我找到了更好的解决方案:
以这种方式声明了服务接口:
void ListaArti(Action<List<ArtiMarziali>, Exception> callback);
以这种方式实现:
public async void ListaArti(Action<List<ArtiMarziali>, Exception> callback)
{
Exception err = null;
List<ArtiMarziali> risultato = null;
try
{
risultato = await MobileService.GetTable<ArtiMarziali>().ToListAsync();
}
catch (Exception ex)
{
err = ex;
}
callback(risultato, err);
}
以这种方式在viewmodel构造函数中调用服务:
IArtiMarzialiService artiService = new ArtiMarzialiService();
artiService.ListaArti((arti, err) =>
{
if (err != null)
{
/// if there is an error should create a property and bind to it for better practices
System.Diagnostics.Debug.WriteLine(err.ToString());
}
else
{
/// set the property
Arti = new ObservableCollection<ArtiMarziali>(arti);
}
});
使用返回void的异步函数我不必在调用者中使用await语句,并且当数据可用时,我使用回调在viewmodel中设置属性。