Null value lingers in cache after Cache.Remove(key)
I added a caching layer between my ASP.NET MVC application and database using the GetOrStore<T>
cache helper below.
This includes caching users' system roles.
When I remove a cached roles object for a signed-in user via HttpRuntime.Cache.Remove(userRoleCacheKey)
, subsequent requests fail with a NullReferenceException because the cache helper is returning a null value for the role cache, even though the cached key should not exist and the helper should regenerate it.
It seems like the cached key lingers around with a null
value. The exception won't budge until I request a role-heavy page a few seconds later.
Why is my cache breaking?
public static class CacheExtensions
{
public static T GetOrStore<T>(this Cache cache, string key, Func<T> generator)
{
var result = cache.Get(key);
if (result == null)
{
result = generator();
if (result != null) // can't store null values in cache.
{
cache[key] = result;
}
}
return (T)result;
}
}
Here is the code that fetches the user's roles and caches it:
public override string[] GetRolesForUser(string userId)
{
return HttpRuntime.Cache.GetOrStore<string[]>(
"RolesForUser[" + userId + "]",
() => Con.Query<string>("SELECT Role FROM vw_UserRo开发者_运维百科les WHERE UserId = @userId", new { userId = Guid.Parse(userId) }).ToArray());
}
where Con
retrieves an open IDbConnection
.
Minor issue in your code that can hide the problem from you:
if (result != null) // can't store null values in cache.
{
cache[key] = result;
}
What about else
clause? The result returned anyway, even if it is null value. Throw InvalidOperationException
in that case and debug your queries passed as generator
parameter.
精彩评论