【问题标题】:mvvm light async call in viewmodel constructorviewmodel 构造函数中的 mvvm light 异步调用
【发布时间】:2013-12-27 18:01:19
【问题描述】:

我正在使用便携式版本的 mvvmlight 开发一个 win phone 8 应用程序。

在创建 ViewModel 时,我必须调用使用 Azure 移动服务 Sdk 从 Azure 移动服务读取数据的服务。

Sdk api 使用 async /await 来完成工作,我无法在 ViewModel 或 Service costructor 中进行异步调用。

代码是这样的:

    public  ListaArtiModel(INavigate navigationService)
    {
        _navigationService = navigationService;

        ArtiMarzialiService artiService = new ArtiMarzialiService();
        List<ArteMarziale>risultato = await artiService.ListaArti();

    }

编译器告诉

错误 1 ​​'await' 运算符只能在异步方法中使用。考虑使用“异步”修饰符标记此方法并将其返回类型更改为“任务”。

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

【问题讨论】:

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


    【解决方案1】:

    我的AsyncEx library 中有一个"task notifier" type,它本质上是Task&lt;T&gt;INotifyPropertyChanged 包装器。你可以这样使用它:

    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.IsFaultedArti.ErrorMessage

    【讨论】:

      【解决方案2】:

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

      一般来说,类构造函数应该尽可能简单,并且你应该避免在构造函数中做任何长时间运行或潜在异常容易发生的工作

      【讨论】:

      【解决方案3】:

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

      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. 以这种方式在视图模型构造函数中调用服务:

        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 中设置属性。

      【讨论】:

        猜你喜欢
        • 2017-04-08
        • 2017-10-18
        • 2015-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-04
        • 2020-07-28
        相关资源
        最近更新 更多