在viewmodel构造函数中进行mvvm light异步调用

时间:2013-12-27 18:01:19

标签: azure mvvm asynchronous windows-phone-8 mvvm-light

我正在使用便携版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'。

我该如何解决这个问题? 谢谢,   卢卡

3 个答案:

答案 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.ResultArti.IsFaulted等。

答案 1 :(得分:1)

您应该重新设计ViewModel,使其具有用于设置ViewModel的LoadDataAsync()InitializeAsync()方法

通常,类构造函数应尽可能简单,并且应避免在构造函数中执行任何长时间运行或可能异常的工作

答案 2 :(得分:1)

我认为我找到了更好的解决方案:

  1. 以这种方式声明了服务接口:

    void ListaArti(Action<List<ArtiMarziali>, Exception> callback);
    
  2. 以这种方式实现:

    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);
    }
    
  3. 以这种方式在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);
      }
    });
    
  4. 使用返回void的异步函数我不必在调用者中使用await语句,并且当数据可用时,我使用回调在viewmodel中设置属性。