MVVM模型中的非阻塞延迟加载属性

Gre*_*ech 12 silverlight wpf lazy-loading mvvm inotifypropertychanged

我是MVVM的新手,所以如果这个问题有一个众所周知的解决方案,请原谅.

我们正在构建一组模型类,它们具有一些预先加载的核心属性,以及一些可以通过进行Web API调用来按需加载延迟的其他属性(更新:澄清,它将是一个每个延迟加载的属性的Web API调用).

而不是拥有多个模型,拥有一个带有延迟加载逻辑的单个模型似乎是明智的.但是,似乎懒惰加载的属性在访问时不应该阻塞,因此当View绑定到ViewModel并且它绑定到Model时,我们不会阻止UI线程.

因此,我正在考虑一种模式,当模型上的惰性属性被访问时,它开始异步获取,然后立即返回默认值(例如null).异步提取完成后,它将引发一个PropertyChanged事件,以便ViewModel/View可以重新绑定到获取的值.

我已经尝试过了,它看起来效果很好,但是想知道:

  1. 我还没有发现这种方法有什么缺陷,但随着应用程序的复杂性增加,会遇到什么问题?
  2. 这个问题是否存在于框架中,或者被广泛用作第三方框架的一部分?

Rac*_*hel 7

我过去做了类似的事情,我一直忘记的一件事是你不能通过任何类型的代码调用你的异步属性并期望它有一个值.

所以,如果我懒加载一个列表Customer.Products,我无法Customer.Products.Count在代码隐藏中引用,因为它第一次被称为值为NULL或0(取决于我是否创建了一个空白集合)

除此之外,它对绑定非常有用.我正在使用Async CTP库来进行异步调用,我发现这对于这样的事情非常棒.

public ObservableCollection<Products> Products
{
    get
    {
        if (_products == null)
            LoadProductsAsync();

        return _products;
    }
    set { ... }
}

private async void LoadProductsAsync()
{
    Products = await DAL.LoadProducts(CustomerId);
}
Run Code Online (Sandbox Code Playgroud)

更新

我记得我遇到的另一件事是实际上是NULL的数据.如果Customer.Products实际从服务器返回NULL值,我需要知道异步方法已正确运行并且实际值为null,因此它不会重新运行异步方法.

如果有人在第一次异步调用完成之前第二次调用Get方法,我也不希望异步方法运行两次.

我当时通过Is[AsyncPropertyName]Loading/ed为每个异步属性创建一个属性并在第一次异步调用期间将其设置为true 来解决这个问题,但是我不必为所有异步属性创建额外的属性.