I am caching data in an ASP.NET website through the System.Web.Caching.Cache-Class, because retrieving the data is very costly and it changes only once in a while, when our content people change data in the backend.
So I create the data in Application_Start and store it in Cache, with an expiration time of 1 day.
When accessing the data (happens on many pages of the website), I have something like this now in a static CachedData class:
public static List<Kategorie> GetKategorieTitelListe(Cache appCache)
{
// get Data out of Cache
List<Kategorie> katList = appCache[CachedData.NaviDataKey] as List<Kategorie>;
// Cache expired, retrieve and store again
if (katList == null)
{
katList = DataTools.BuildKategorienTitelListe();
appCache.Insert(CachedData.NaviDataKey, katList, null, DateTime.Now.AddDays(1d), Cache.NoSlidingExpiration);
}
return katList;
}
The problem I see with this code is that its not threadsafe. If two users open two of these pages at the same time and the cache just ran out, there is a risk the data while be retrieved multiple times.
But if I lock the method body, I will run into performance troubles, because only one user at a time can get the data list.
Is there an easy way to prevent this? What's best practice for a case like this?