I have an ASP.NET web app, which calls an expensive operation and needs to cache the data. The call to the operation needs to be made only one time, even if there are concurrent requests.
The idea is that I keep the data in a ConcurrentDictionary
. The first time any request access the dictionary, a Lazy record is inserted to defer the work for later. Any subsequent requests should get back the same record. Also the expensive operation uses await because of usage of HttpClient
.
I tried to implement this with the following code
private static readonly ConcurrentDictionary<Guid, Lazy<Task<List<ProductsList>>>> cache =
new ConcurrentDictionary<Guid, Lazy<Task<List<ProductsList>>>>();
public async Task<List<ProductsList>> Get(AnalysisParams aParams, string refUrlApi)
{
return await cache.GetOrAdd(aParams.Project_ID, (pid) => new Lazy<Task<List<ProductsList>>>(
async () => await Task.Run(async() => await Utils.GetProductsList(aParams, refUrlApi))
)).Value;
}
However when I check my logs, I can see that the expensive operation is called multiple times through the day instead of once. The instance where the web app is running is not restarted according to the admin.
Maybe I have messed up with the async/await? How can I achieve what I need?