使用Async的延迟加载属性

Sat*_*nix 5 c# asynchronous

我已经学会了在我的存储库中延迟加载属性.现在我想这样做,但我还需要从网页加载一些东西(使用Httpclient),这意味着我的属性将是异步的.

public async Task<List<NewsModel>> News
{
    get
    {
        if (_news == null)
        {
            CacheProvider cache = new CacheProvider();
            object cachedNews = cache.Get("news");

            if (cachedNews == null)
            {
                var client = new HttpClient();
                // await HttpResponse
            }

        }
        return _news;
    }

    set
    {
        _news = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,视觉工作室告诉我

"修饰符异步对此项无效"

同时在第一行突出显示"新闻"一词.

是否有可能做到这一点?或者我必须编写一个单独的方法?

Ste*_*ary 11

不支持异步属性.我在博客上描述了一些变通方法.

在你的情况下,听起来像异步延迟初始化将是一个很好的解决方案(也在我的博客上描述).


ang*_*son 5

首先,具有副作用的特性通常不是那么好.

在这种情况下,只需读取此属性即可启动线程,某些网络流量以及远程服务器上的某些处理.

这应该是一种方法,而不是财产.

其次,编译器是正确的,属性不允许是异步的.现在,您绝对可以编写一个返回异步任务的属性,但不允许您使用该async关键字.基本上只是async从属性声明中删除关键字.

但是async对于属性不合法的事实是另一个线索,你应该写一个方法,而不是一个属性.

注意async在您发布的代码中实际上并不需要该关键字,因为您实际上并未使用该await关键字.因此,您可以完全删除async关键字,因为它不是必需的.实际上,如果您要将其更改为方法,编译器会告诉您由于您没有使用它是不必要的await. (在OP编辑问题后删除.)

  • _“首先,有副作用的属性通常不是那么好”_ - 好吧,不,这就是**代理类**与**按需/延迟加载**加载的工作方式,例如_ORMs_ (2认同)
  • 我同意“有副作用的特性通常不是那么好”,但我认为它不适用于这里。属性不应改变系统的逻辑状态。我不认为加载数据是副作用。查询属性就是在问问题。努力回答这个问题是一个预期的效果。 (2认同)