8

我已经学会了在我的存储库中延迟加载属性。现在我想这样做,但我还需要从网页加载一些东西(使用 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;
    }
}

但是,视觉工作室告诉我

“修饰符异步对此项目无效”

同时突出显示第一行中的“新闻”一词。

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

4

4 回答 4

13

不支持异步属性。我在我的博客上描述了一些解决方法。

在您的情况下,听起来异步延迟初始化将是一个很好的解决方案(也在我的博客中进行了描述)。

于 2013-07-31T16:32:17.610 回答
8

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

在这种情况下,简单地读取这个属性就会启动一个线程、一些网络流量和远程服务器上的一些处理。

这应该是一个方法,而不是一个属性。

其次,编译器是对的,属性是不允许异步的。现在,你绝对可以一个返回异步任务的属性,但是你不能使用async关键字。基本上只是async从属性声明中去掉关键字。

async但是属性不合法的事实是另一个线索,您应该编写一个方法,而不是一个属性。

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

于 2013-07-31T16:21:35.840 回答
3

您可以使用返回任务的延迟属性:

class MyClass
{
    readonly Lazy<Task<string>> _text;

    public MyClass()
    {
        _text = new Lazy<Task<string>>(async () =>
        {
            //... await something
            return "Hello!"
        });
    }

    async Task DoSomething()
    {
       var text = await _text.Value;
       //...
    }
}
于 2016-12-14T11:42:05.257 回答
1

我认为这个问题是相关的。

简而言之 - 不支持异步属性。

于 2013-07-31T16:22:25.197 回答