异步延迟加载属性
本文关键字:属性 延迟加载 异步 | 更新日期: 2023-09-27 18:25:37
我已经学会了在存储库中延迟加载属性。现在我想这么做,但我还需要从网页加载一些东西(使用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;
}
}
然而,视觉工作室告诉我
"修饰符async对此项无效"
同时在第一行突出显示单词"新闻"。
有可能做到这一点吗?还是我必须写一个单独的方法?
在您的情况下,异步延迟初始化听起来是一个很好的解决方案(在我的博客中也有描述)。
首先,具有副作用的属性通常并不那么好。
在这种情况下,简单地读取这个属性就会启动线程、一些网络流量和远程服务器上的一些处理。
这应该是一个方法,而不是属性。
其次,编译器是对的,属性不允许是异步的。现在,您肯定可以写入一个返回异步任务的属性,但不允许使用async
关键字。基本上只需从属性声明中去掉async
关键字。
但是async
在属性上是不合法的,这是另一条线索,表明您应该编写一个方法,而不是属性。
注意在您发布的代码中实际上并不需要(在OP编辑问题后删除。)async
关键字,因为您实际上并没有在其中使用await
关键字。因此,您可以简单地完全删除async
关键字,因为它不是必需的。事实上,如果您要将其更改为方法,编译器会告诉您这是不必要的,因为您没有使用await
您可以使用Lazy属性来返回Task:
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;
//...
}
}
我认为这个问题是相关的。
简而言之,不支持异步属性。