從緩存中讀取數據,緩存定時更新

背景:有時候數據量很大,又須要很複雜的計算過程,實時從數據庫去取的話會要很長時間,併發量大的話可能致使整個頁面崩潰,由於只是一個小項目,只有這一個功能須要,又不是特別重要的功能,因此不考慮用redis,這個時候考慮用的是系統本身的緩存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);
        }
    }
相關文章
相關標籤/搜索