从缓存中读取数据,缓存定时更新
背景:有时候数据量很大,又需要很复杂的计算过程,实时从数据库去取的话会要很长时间,并发量大的话可能导致整个页面崩溃,因为只是一个小项目,只有这一个功能需要,又不是特别重要的功能,所以不考虑用redis,这个时候考虑用的是系统自己的缓存
static List<RecommendRank> _cachedRecommendList = null;//定义一个全局的静态的缓存列表 // 先取到最近的一次缓存结果 List<RecommendRank> recommendList = _cachedRecommendList; // 取系统缓存 string cacheKey = "@_JY_RECOMMEND_LIST"; _cachedRecommendList = (List<RecommendRank>)SystemCache.GetCacheObject(cacheKey); if (_cachedRecommendList != null) { // 如果系统缓存有,更新返回 recommendList = _cachedRecommendList; } else { // 如果系统缓存没有或失效 Task updateTask = new Task(() => { lock (this.GetType()) { _cachedRecommendList = (List<RecommendRank>)SystemCache.GetCacheObject(cacheKey, () => { .....计算结果集的过程 return recommendList1; }, TimeSpan.FromMinutes(60)); } }); updateTask.Start(); if (recommendList == null) { // 仅在最近没有缓存结果的时候才等待任务返回 updateTask.Wait();//只有第一次打开的时候会等待返回,其它默认取上一次缓存数据然后异步更新缓存 recommendList = _cachedRecommendList; } }
/// <summary> /// 系统缓存池 /// </summary> public static class SystemCache { static Dictionary<string, SystemCacheRec> _cacheTable; public delegate object CreateNew(); static SystemCache() { _cacheTable = new Dictionary<string, SystemCacheRec>(); } /// <summary> /// 存储一个缓存对象 /// </summary> /// <param name="key"></param> /// <param name="obj"></param> /// <param name="lifeTime"></param> public static void StoreCacheObject(string key, object obj, TimeSpan lifeTime) { SystemCacheRec rec = new SystemCacheRec(); rec.obj = obj; rec.storeTime = DateTime.Now; rec.lifeTime = lifeTime; lock (_cacheTable) { _cacheTable[key] = rec; } } /// <summary> /// 获取一个缓存对象,如果超时,返回空值 /// </summary> /// <param name="key"></param> /// <returns></returns> public static object GetCacheObject(string key) { lock (_cacheTable) { if (!_cacheTable.ContainsKey(key)) { return null; } var rec = _cacheTable[key]; if (rec.storeTime + rec.lifeTime >= DateTime.Now) { return rec.obj; } else { _cacheTable.Remove(key); return null; } } } /// <summary> /// 获取缓存值,如果没有或超期,使用一个代理创建一个新的值 /// </summary> /// <param name="key"></param> /// <param name="createNew"></param> /// <param name="lifeTime"></param> /// <returns></returns> public static object GetCacheObject(string key, CreateNew createNew, TimeSpan lifeTime) { var obj = GetCacheObject(key); if (obj == null) { var newObj = createNew(); lock (_cacheTable) { obj = GetCacheObject(key); if (obj == null) { obj = newObj; StoreCacheObject(key, obj, lifeTime); } } } return obj; } /// <summary> /// 清空缓存 /// </summary> public static void ClearCache() { lock (_cacheTable) { _cacheTable.Clear(); } } class SystemCacheRec { public object obj = null; public DateTime storeTime = DateTime.Now; public TimeSpan lifeTime = TimeSpan.FromMinutes(5); } }