Created
May 4, 2012 14:39
-
-
Save alfeg/2595170 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <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