【问题标题】:Null value lingers in cache after Cache.Remove(key)Cache.Remove(key) 后空值在缓存中徘徊
【发布时间】:2011-12-02 03:46:05
【问题描述】:

我使用下面的 GetOrStore<T> 缓存助手在我的 ASP.NET MVC 应用程序和数据库之间添加了一个缓存层。

这包括缓存用户的系统角色。

当我通过HttpRuntime.Cache.Remove(userRoleCacheKey) 删除已登录用户的缓存角色对象时,后续请求会失败并出现 NullReferenceException,因为缓存助手正在为角色缓存返回空值,即使缓存的键不应该存在并且助手应该重新生成它。

似乎缓存的密钥带有null 值。直到几秒钟后我请求一个角色繁重的页面,该异常才会让步。

为什么我的缓存坏了?

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

这里是获取用户角色并缓存它的代码:

public override string[] GetRolesForUser(string userId)
{
    return HttpRuntime.Cache.GetOrStore<string[]>(
        "RolesForUser[" + userId + "]",
        () => Con.Query<string>("SELECT Role FROM vw_UserRoles WHERE UserId = @userId", new { userId = Guid.Parse(userId)  }).ToArray());
}

Con 检索打开的IDbConnection

【问题讨论】:

  • 缓存中是否有任何对象的类覆盖相等性(和== 运算符)?
  • 好问题。我不知道,但这个角色对象是string[]
  • 添加了在我的自定义角色提供程序中使用缓存助手的代码。
  • string[]对象的情况下,可能NullReferenceException不是由对象的null值引起的,而是空数组?例如。你在它上面调用 First() 方法并得到异常。

标签: asp.net-mvc exception caching


【解决方案1】:

代码中的小问题可以隐藏问题:

if (result != null) // can't store null values in cache.
{
    cache[key] = result;
}

else 子句呢?无论如何都会返回结果,即使它是空值。在这种情况下抛出 InvalidOperationException 并调试作为 generator 参数传递的查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多