从缓存中读取数据,缓存定时更新

背景:有时候数据量很大,又需要很复杂的计算过程,实时从数据库去取的话会要很长时间,并发量大的话可能导致整个页面崩溃,因为只是一个小项目,只有这一个功能需要,又不是特别重要的功能,所以不考虑用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);
        }
    }

 

posted @ 2019-10-10 10:16  过一天日子修一天缘  阅读(1546)  评论(0编辑  收藏  举报