Created
August 25, 2013 17:19
-
-
Save pseudomuto/6335102 to your computer and use it in GitHub Desktop.
Blog Code: Efficient Thread-Safe Caching with ASP.NET
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
public class CacheManager | |
{ | |
// CLR guarantees thread-safety during initialization | |
private static Dictionary<string, object> CacheKeyDictionary = new Dictionary<string, object>(); | |
public static TObj GetCachedObject<TObj>(string cacheKey, Func<TObj> creator) where TObj : class | |
{ | |
var cache = HttpContext.Current.Cache; | |
var obj = cache[cacheKey] as TObj; | |
if (obj == null) | |
{ | |
// get the lock object | |
var lockObject = GetCacheLockObject(cacheKey); | |
lock (lockObject) | |
{ | |
// double check...if-lock-if | |
obj = cache[cacheKey] as TObj; | |
if (obj == null) | |
{ | |
obj = creator.Invoke(); | |
cache.Insert(cacheKey, obj); | |
} | |
} | |
} | |
return obj; | |
} | |
private static object GetCacheLockObject(string cacheKey) | |
{ | |
if (!CacheKeyDictionary.ContainsKey(cacheKey)) | |
{ | |
// lock on the whole dictionary | |
lock (CacheKeyDictionary) | |
{ | |
// check again...always remember: if-lock-if | |
if (!CacheKeyDictionary.ContainsKey(cacheKey)) | |
{ | |
CacheKeyDictionary.Add(cacheKey, new object()); | |
} | |
} | |
} | |
return CacheKeyDictionary[cacheKey]; | |
} | |
} |
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
private IEnumerable<string> GetExpensiveNameList() | |
{ | |
return CacheManager.GetCachedObject<IEnumerable<string>>( | |
"CacheKeyHere", | |
() => | |
{ | |
// perform expensive lookup here... | |
return Enumerable.Empty<string>(); | |
} | |
); | |
} |
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
private TObj GetCachedObject<TObj>(string cacheKey, Func<TObj> creator) where TObj : class | |
{ | |
Cache cache = this.HttpContext.Cache; | |
TObj obj = cache[cacheKey] as TObj; | |
if (obj == null) | |
{ | |
lock (cache) | |
{ | |
//look it up again in case a previous request created it already | |
obj = cache[cacheKey] as TObj; | |
if (obj == null) | |
{ | |
obj = creator.Invoke(); | |
cache.Insert(cacheKey, obj); | |
} | |
} | |
} | |
return obj; | |
} |
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
private TObj GetCachedObject<TObj>(string cacheKey, Func<TObj> creator) where TObj : class | |
{ | |
Cache cache = this.HttpContext.Cache; | |
TObj obj = cache[cacheKey] as TObj; | |
if (obj == null) | |
{ | |
lock (cache) | |
{ | |
obj = creator.Invoke(); | |
cache.Insert(cacheKey, obj); | |
} | |
} | |
return obj; | |
} |
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
private TObj GetCachedObject<TObj>(string cacheKey, Func<TObj> creator) where TObj : class | |
{ | |
TObj obj = this.HttpContext.Cache[cacheKey] as TObj; | |
if (obj == null) | |
{ | |
obj = creator.Invoke(); | |
this.HttpContext.Cache.Insert(cacheKey, obj); | |
} | |
return obj; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you very much for this! It really helped.