MVVM c#如何将异步数据加载到属性中?

时间:2017-04-12 11:58:49

标签: c# wpf mvvm

我想知道是否有更好的方法将异步数据加载到属性中。现在我创建一个异步函数并在属性的Get部分中引发一个Task,如下所示:

private ObservableCollection<CProyecto> prope;

public ObservableCollection<CProyecto> Prope
{
    get 
    {
        if (prope == null)
        {
            Task.Run(()=> LoadData()).Wait();
        }

        return proyectos;
    }
    set 
    { 
        prope = value; 
        RaisePropertyChanged(); 
    }
}

async private Task LoadData() 
{
    Prope = await clsStaticClassDataLoader.GetDataFromWebService();
}

这种方法有效,但我不喜欢使用.Wait,因为如果服务没有快速响应,它可以冻结屏幕。

你能指导我这件事吗?

提前致谢

3 个答案:

答案 0 :(得分:6)

我建议您在async MVVM data-binding上阅读我的MSDN文章。我a library提供NotifyTask<T> type,可以这样使用:

public class MyClass : INotifyPropertyChanged
{
  public NotifyTask<ObservableCollection<CProyecto>> Prope { get; private set; }

  public MyClass()
  {
    // Synchronously *start* the operation.
    Prope = NotifyTask.Create(LoadDataAsync());
  }

  async private Task<ObservableCollection<CProyecto>> LoadDataAsync()
  {
    return await clsStaticClassDataLoader.GetDataFromWebService();
  }
}

然后您的数据绑定将在Prope.Result上运行。

此方法的优点是您还可以使用数据绑定来隐藏/显示繁忙指示符(Prope.IsNotCompleted),在数据可用时显示控件(Prope.IsSuccessfullyCompleted)和错误通知({{ 1}} / Prope.IsFaulted)。

另外,如果您愿意,可以指定非Prope.ErrorMessage默认值:

null

答案 1 :(得分:3)

我处理这个的方法是在构造对象时开始加载属性的过程,但我没有等待结果。由于属性在填充时通知,绑定工作正常。基本上它的工作原理如下:

null

这非常有效,并且不会在UI中造成任何延迟或卡顿。如果您希望集合永远不是prope(IMO的一个好习惯),您可以使用空集合预初始化sudo iptables-save | grep 80 -A IN_public_allow -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT 字段。

答案 2 :(得分:0)

您当前对Prope属性的实现没有多大意义。在后台线程上执行LoadData方法毫无意义,因为当您调用Wait()时,无论如何都会阻塞主线程。您也可以直接在Wait()方法返回的任务上调用LoadData()

//BAD IMPLEMENTATION!
private ObservableCollection<CProyecto> prope;
public ObservableCollection<CProyecto> Prope
{
    get
    {
        if (prope == null)
            LoadData().Wait();
        return proyectos;
    }
    set { prope = value; RaisePropertyChanged(); }
}

上述实施仍然很糟糕。属性的getter不应该执行异步操作。你应该阅读@Stephen Cleary关于这个主题的博文:https://blog.stephencleary.com/2013/01/async-oop-3-properties.html

...并在NotifyTaskCompletion库中查看他的AsyncEx类型:https://github.com/StephenCleary/AsyncEx