How to implement a fast concurrent Lazy Load Cache in C#.
private readonly object _syncLock = new object();
private IList<Product> _localCache;
public IList<Product> GetProducts()
{
// declare local variable for cache access
// and use it to be safe on sudden cache resetting
List<Product> result = _localCache;
if (result == null)
{
lock (_syncLock)
{
// recheck condition after acquiring lock
// to be sure cache is not loaded while waiting for the lock
result = _localCache;
if (result == null)
{
// it is important to first store result in local variable
// and only after in cache because in between cache
// might be reset
result = LoadProductsFromDatabase();
_localCache = result;
}
}
}
// important -- return local variable and not _localCache
// above code guaranties that result will have value
// on the other hand _localCache might be reset at any time
return result;
}
public void Reset()
{
// no need for any kind of locking
// because our lazy load can handle resetting at any time
_localCache = null;
}
protected IList<Product> LoadProductsFromDatabase()
{
// load from db...
}