You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Framework 4.8分布式缓存实现及滑动缓存方案问询

.NET Framework 4.8 基于Redis实现滑动分布式缓存方案

原代码问题分析

  • 错误将StackExchange.Redis的IDatabase强制转换为ASP.NET Core专属的IDistributedCache,两者无继承关系,直接导致_distributedcache实例无效,触发空引用异常。
  • 构造函数中重复赋值_distributedcache,逻辑冗余且错误。

解决方案:基于StackExchange.Redis原生实现滑动缓存

无需依赖ASP.NET Core的IDistributedCache,直接基于你已验证可行的RedisCache类扩展滑动缓存逻辑。滑动缓存的核心是每次读取缓存时自动刷新键的过期时间,确保键在被访问时不会过期。

1. 扩展缓存接口(ICache)

添加滑动缓存的方法定义:

public interface ICache
{
    Task<T> GetCache<T>(string key);
    Task<bool> SetCache<T>(string key, T value, int timeSpan);
    // 新增滑动缓存方法
    Task<T> GetSlidingCache<T>(string key, TimeSpan slidingExpiration);
    Task<bool> SetSlidingCache<T>(string key, T value, TimeSpan slidingExpiration);
}

2. 修改RedisCache类实现滑动逻辑

基于现有可运行的RedisCache,添加滑动缓存的实现:

public class RedisCache : ICache
{
    private readonly IDatabase _cache;
    private readonly ConnectionMultiplexer _redisConnection;

    public RedisCache()
    {
        var redisConStr = ConfigurationManager.ConnectionStrings["Redis"].ConnectionString;
        _redisConnection = ConnectionMultiplexer.Connect(redisConStr);
        _cache = _redisConnection.GetDatabase();
    }

    // 保留原有的GetCache和SetCache方法不变
    public async Task<T> GetCache<T>(string key)
    {
        var redisObj = await _cache.StringGetAsync(key);
        if (!redisObj.HasValue)
            return default(T);

        return JsonConvert.DeserializeObject<T>(redisObj, new JsonSerializerSettings
        {
            ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
            PreserveReferencesHandling = PreserveReferencesHandling.Objects
        });
    }

    public async Task<bool> SetCache<T>(string key, T value, int timeSpan)
    {
        if (value == null)
            return true;

        var strVal = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings
        {
            ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
            PreserveReferencesHandling = PreserveReferencesHandling.Objects
        });

        var cacheTimeSpan = timeSpan > 0 ? TimeSpan.FromMinutes(timeSpan) : TimeSpan.FromMinutes(10);
        return await _cache.StringSetAsync(key, strVal, cacheTimeSpan);
    }

    // 实现滑动缓存获取方法:读取值后刷新过期时间
    public async Task<T> GetSlidingCache<T>(string key, TimeSpan slidingExpiration)
    {
        var redisObj = await _cache.StringGetAsync(key);
        if (!redisObj.HasValue)
            return default(T);

        // 每次读取成功后,刷新键的过期时间(滑动核心逻辑)
        await _cache.KeyExpireAsync(key, slidingExpiration);

        return JsonConvert.DeserializeObject<T>(redisObj, new JsonSerializerSettings
        {
            ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
            PreserveReferencesHandling = PreserveReferencesHandling.Objects
        });
    }

    // 实现滑动缓存设置方法:初始设置过期时间
    public async Task<bool> SetSlidingCache<T>(string key, T value, TimeSpan slidingExpiration)
    {
        if (value == null)
            return true;

        var strVal = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings
        {
            ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
            PreserveReferencesHandling = PreserveReferencesHandling.Objects
        });

        // 设置键值时指定初始滑动过期时间
        return await _cache.StringSetAsync(key, strVal, slidingExpiration);
    }
}

3. 调用示例

获取滑动缓存

var slidingExpiration = TimeSpan.FromMinutes(30);
List<EmployeeRole> employeeRoles = _cache.GetSlidingCache<List<EmployeeRole>>(Constants.CACHE_CALENDARROLES, slidingExpiration).GetAwaiter().GetResult();

设置滑动缓存

var slidingExpiration = TimeSpan.FromMinutes(30);
var employeeRoles = ReadEmployeeRoles(i_RoleId, i_VendorId);
await CacheHelper.Cache.SetSlidingCache<List<ModelEmployeeRole>>(Constants.CACHE_EmployeeROLES, employeeRoles, slidingExpiration);

关键说明

  • 滑动过期依赖KeyExpireAsync方法,每次读取缓存成功后刷新键的过期时间,确保键在持续访问时不会过期。
  • 若需要统一管理过期时间,可将滑动过期时长配置到web.config中,避免硬编码。
  • 避免在同步代码中直接使用GetAwaiter().GetResult(),建议将调用方改为异步方法,防止死锁风险。

内容的提问来源于stack exchange,提问作者Susmitha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 03:11:29