Skip to content

Instantly share code, notes, and snippets.

@alfeg
Created May 4, 2012 14:39
Show Gist options
  • Save alfeg/2595170 to your computer and use it in GitHub Desktop.
Save alfeg/2595170 to your computer and use it in GitHub Desktop.
/// <summary>
/// Controls access to the cached values.
/// </summary>
private static ReaderWriterLockSlim mutex = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
/// <summary>
/// Gets a values from the cache, adding it if required.
/// </summary>
/// <typeparam name="T">The type of the value.</typeparam>
/// <param name="cacheParameters">The name of the value used to identify it in the cache.</param>
/// <param name="valueFactory">The factory to create the value if it is not present in the cache.</param>
/// <returns>The value as stored in the cache.</returns>
public static T GetFromCache<T>(this IDataCache dataCache, DataCacheParameters cacheParameters, Func<T> valueFactory)
{
using (var diag = new PerfDiagnostics())
{
diag.Write("Start");
mutex.EnterReadLock();
try
{
object result = dataCache.Get(cacheParameters);
if (result != null)
{
diag.Write("Return result");
return (T) result;
}
}
finally
{
mutex.ExitReadLock();
}
diag.Write("Before enter write block");
mutex.EnterUpgradeableReadLock();
diag.Write("After enter write block");
try
{
object result = dataCache.Get(cacheParameters);
if (result == null)
{
diag.Write("Waiting data from factory");
// allow reading while calculating a new value
// factory methods are not allowed to read from the cache themselves (no recursion)
var value = valueFactory();
diag.Write("Got data from factory");
mutex.EnterWriteLock();
diag.Write("Got data from factory. Inside of write lock");
try
{
dataCache.Add(cacheParameters, value);
}
finally
{
diag.Write("Got data from factory. Exit from write lock");
mutex.ExitWriteLock();
}
diag.Write("Return data from factory");
return value;
}
else
{
diag.Write("After enter write block. Return data from factory");
return (T) result;
}
}
finally
{
mutex.ExitUpgradeableReadLock();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment