我已经在我的存储库中学习了延迟加载属性。现在我想这样做,但我还需要从网页加载一些东西(使用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;
}
}
然而,visual studio告诉我
“修饰符异步对此项目无效”
同时在第一行突出显示“新闻”一词。
有可能这样做吗?或者我是否必须编写单独的方法?
答案 0 :(得分:10)
不支持异步属性。我在博客上描述了number of workarounds。
在您的情况下,听起来asynchronous lazy initialization会是一个很好的解决方案(我的博客上也有描述)。
答案 1 :(得分:5)
首先,具有副作用的属性通常不是那么好。
在这种情况下,只需读取这个属性就会启动一个线程,一些网络流量,以及远程服务器上的一些处理。
这应该是一种方法,而不是财产。
其次,编译器是正确的,不允许属性是异步的。现在,您绝对可以编写返回异步任务的属性,但不允许您使用async
关键字。基本上只是从属性声明中删除async
关键字。
但async
在属性上不合法的事实是另一个线索,你应该写一个方法,而不是一个属性。
注意您发布的代码中实际上并不需要 (在OP编辑问题后删除了。 ) async
关键字,因为您实际上并未使用await
关键字。因此,您只需完全删除async
关键字,因为它不是必需的。实际上,如果你要将其更改为方法,编译器会告诉你没有必要,因为你没有使用await
。
答案 2 :(得分:3)
您可以使用返回任务的Lazy属性:
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;
//...
}
}
答案 3 :(得分:1)
我认为this question是相关的。
简而言之 - 不支持异步属性。