I've learned to lazy load properties in my repository. Now I'd like to do that, but I also need to load something from a web page (using Httpclient) which means my property will be async.
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;
}
}
However, visual studio is telling me that
"The modifier async is not valid for this item"
while highlighting the word "News" in the first line.
Is it possible to do this? Or do I have to write a separate method?
Asynchronous properties are not supported. I describe a number of workarounds on my blog.
In your case, it sounds like asynchronous lazy initialization would be a good solution (also described on my blog).
First of all, properties with side-effects are usually not all that good.
In this case, simply reading this property would kick off a thread, some network traffic, and some processing on a remote server.
This should be a method, not a property.
Secondly, the compiler is right, properties are not allowed to be asynchronous. Now, you can definitely write a property that returns an asynchronous task, but you're not allowed to use the
async
keyword. Basically just take away theasync
keyword from the property declaration.But the fact that
async
is not legal on properties is another clue that you should write a method, not a property.Note The(Removed after OP edited the question.)async
keyword is not actually required in the code you've posted, since you're not actually using theawait
keyword in there. As such, you can simply remove theasync
keyword altogether, since it is not required. In fact, if you were to change this over to a method, the compiler will tell you that it is unnecessary since you're not usingawait
.I think this question is related.
In short - async properties are not supported.
You can use a Lazy property that returns a Task: