System.Runtime.Caching.MemoryCache 缓存应用实践

需求:将高频且耗时,且数据基本没变化的查询结果,用缓存提升性能。

实现:继承MemoryCache,重载部分方法,在数据库中持久化缓存数据。

本文使用了两级缓存,不用考虑缓存加载。服务重启,读不到内存缓存,会从数据库读取一次。

//泛型类,内部进行二进制序列化与反序列化
using System;
using System.Collections.Specialized;
using System.IO;
using System.Runtime.Caching;
using System.Runtime.Serialization.Formatters.Binary;

namespace xxx.BLL {
    public class DBTCache<T> : MemoryCache where T : class, new() {

        public DBTCache(string name, NameValueCollection config = null) : base(name, config) { }

        public override bool Add(string key, object value, DateTimeOffset dtime, string regionName = null) {
            var mem = new MemoryStream();
            new BinaryFormatter().Serialize(mem, value);
            if (base.Contains(key)) base.Set(key, mem.GetBuffer(), dtime, regionName);
            else base.Add(key, mem.GetBuffer(), dtime, regionName);
            var data = new Model.__Cache() { sKey = key, vObj = mem.GetBuffer(), dTime = dtime.DateTime };
            mem.Dispose();
            return DB.Update(data) || DB.Insert(data);
        }

        public override object Get(string key, string regionName = null) {
            if (!base.Contains(key, regionName)) {
                var cache = DB.GetFirst(t => t.sKey == key);
                if (cache is null) return null;
                else base.Add(key, cache.vObj, cache.dTime, regionName);
            }
            return new BinaryFormatter().Deserialize(new MemoryStream((byte[])base.Get(key, regionName))) as T;
            //return base.Get(key, regionName);
        }

        public bool Clear() {
            DB.Context.DbMaintenance.TruncateTable("__Cache");
            base.Trim(100);
            return true;
        }

        private static DAL.IEntity<Model.__Cache> _db = null;
        private DAL.IEntity<Model.__Cache> DB {
            get {
                if (_db is null) _db = new DAL.IEntity<Model.__Cache>();
                return _db;
            }
        }
    }
}
//调用
 static DBTCache<List<PowerData>> cache = new DBTCache<List<PowerData>>("xxxsssssxxxx");

return cache.Get(key) as List<PowerData>; //get
cache.Add(key, ListTData, DateTime.Now.AddDays(1)); //add

 

另一个通用版本: add/get需要在调用时反/序列化

using System;
using System.Collections.Specialized;
using System.Runtime.Caching;

namespace xxx.BLL {
    public class DBCache : MemoryCache {

        public DBCache(string name, NameValueCollection config = null) : base(name, config) { }

        public override bool Add(string key, object value, DateTimeOffset dtime, string regionName = null) {
            if (base.Contains(key)) base.Set(key, value, dtime, regionName);
            else base.Add(key, value, dtime, regionName);
            var data = new Model.__Cache() { sKey = key, vObj = (byte[])value, dTime = dtime.DateTime };
            return DB.Update(data) || DB.Insert(data);
        }

        public override object Get(string key, string regionName = null) {
            if (!base.Contains(key, regionName)) {
                var cache = DB.GetFirst(t => t.sKey == key);
                if (cache is null) return null;
                else base.Add(key, cache.vObj, cache.dTime, regionName);
            }
            return base.Get(key, regionName);
        }

        public bool Clear() {
            DB.Context.DbMaintenance.TruncateTable("__Cache");
            base.Trim(100);
            return true;
        }

        private static DAL.IEntity<Model.__Cache> _db = null;
        private DAL.IEntity<Model.__Cache> DB {
            get {
                if (_db is null) _db = new DAL.IEntity<Model.__Cache>();
                return _db;
            }
        }
    }
}


//调用
//static DBCache cache = new DBCache("asfasdafsdafda");
//return new BinaryFormatter().Deserialize(new MemoryStream((byte[])obj)) as List<PowerData>;

//var mem = new MemoryStream();
//new BinaryFormatter().Serialize(mem, data);
//cache.Add(key, mem.GetBuffer(), DateTime.Now.AddDays(1)); 
//mem.Dispose();
View Code

 

posted @ 2022-07-29 11:16  enif  阅读(262)  评论(0编辑  收藏  举报
豫ICP备2021034901号