Skip to main content

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...
}