欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C#笔记之键值对缓存MemoryCache

程序员文章站 2022-06-12 20:24:19
...

缓存简介

系统性能优化的第一步,就是使用缓存

不是说严格满足,看情况,存一次能查3次,就值得缓存(大型项目标准)
字典/省市区/配置文件
公告信息/部门/权限/用户
热搜/类别列表/产品列表

缓存优化性能,核心就是结果重用,下一次请求还是用上一次的结果


缓存究竟哪里用? 满足哪些特点适合用缓存?
访问频繁+耗时耗资源+相对稳定+体积不那么大

使用方法(add填入参数,第一个参数键值,第二个缓存数据,第三个过期时间,10分钟)


//存储多种类型数据
CacheManager.Add("CacheManager" + k.ToString(), k);
CacheManager.Add("CacheManager",new Student(10));


//遍历缓存数据
foreach (var item in CacheManager.GetCacheInstance())
{
    //检测是否是要找的类型
    if(item.Value is Student)
    Console.WriteLine(item.Value);
}

MemoryCacheCache.cs

using System;
using System.Collections.Generic;
using System.Runtime.Caching;
using System.Text.RegularExpressions;

namespace Common
{
    /// <summary>
    /// MemoryCacheCache
    /// </summary>
    public class MemoryCacheCache : ICache
    {
        public MemoryCacheCache() { }

        protected ObjectCache Cache
        {
            get
            {
                return MemoryCache.Default;
            }
        }
        /// <summary>
        /// 获取ObjectCache实例,可以进行遍历
        /// </summary>
        /// <returns></returns>
        public ObjectCache GetCacheInstance()
        {
            return Cache;
        }
        /// <summary>
        /// 读取缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public T Get<T>(string key)
        {
            if (Cache.Contains(key))
            {
                return (T)Cache[key];
            }
            else
            {
                return default(T);
            }
        }

        public object Get(string key)
        {
            return Cache[key];
        }

        /// <summary>
        /// 增加缓存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="data"></param>
        /// <param name="cacheTime">分钟</param>
        public void Add(string key, object data, int cacheTime = 30)
        {
            if (data == null)
                return;

            var policy = new CacheItemPolicy();
            policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime);
            Cache.Add(new CacheItem(key, data), policy);
        }

        /// <summary>
        /// 是否包含
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool Contains(string key)
        {
            return Cache.Contains(key);
        }

        public int Count { get { return (int)(Cache.GetCount()); } }


        /// <summary>
        /// 单个清除
        /// </summary>
        /// <param name="key">/key</param>
        public void Remove(string key)
        {
            Cache.Remove(key);
        }

        /// <summary>
        /// 正则表达式移除
        /// </summary>
        /// <param name="pattern">pattern</param>
        public void RemoveByPattern(string pattern)
        {
            var regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
            var keysToRemove = new List<String>();

            foreach (var item in Cache)
                if (regex.IsMatch(item.Key))
                    keysToRemove.Add(item.Key);

            foreach (string key in keysToRemove)
            {
                Remove(key);
            }
        }

        /// <summary>
        /// 根据键值返回缓存数据
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public object this[string key]
        {
            get { return Cache.Get(key); }
            set { Add(key, value); }
        }

        /// <summary>
        /// 清除全部数据
        /// </summary>
        public void RemoveAll()
        {
            foreach (var item in Cache)
                Remove(item.Key);
        }
    }
}

CacheManager.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Caching;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Common
{
    public class CacheManager
    {
        #region Identity
        private CacheManager()
        { }

        private static ICache cache = null;

        static CacheManager()
        {
            Console.WriteLine("开始缓存的初始化.....");
            //可以创建不同的cache对象
            cache = (ICache)Activator.CreateInstance(typeof(MemoryCacheCache));
            // 这里可以根据配置文件来选择
            //cache = (ICache)Activator.CreateInstance(typeof(CustomerCache));


            //Task.Run(() =>
            //{
            //    while (true)
            //    {
            //        Thread.Sleep(1000 * 60 * 10);
            //        try
            //        {
            //            for (int i = 0; i < cache.Count; i++)
            //            {
            //                cache.
            //            }
            //        }
            //        catch (Exception ex)
            //        {
            //            Console.WriteLine(ex.Message);
            //            continue;
            //        }
            //    }
            //});
        }
        #endregion Identity

        #region ICache
        /// <summary>
        /// 当前缓存数据项的个数
        /// </summary>
        public static int Count
        {
            get { return cache.Count; }
        }

        /// <summary>
        /// 如果缓存中已存在数据项键值,则返回true
        /// </summary>
        /// <param name="key">数据项键值</param>
        /// <returns>数据项是否存在</returns>
        public static bool Contains(string key)
        {
            return cache.Contains(key);
        }

        /// <summary>
        /// 获取缓存数据
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T GetData<T>(string key)
        {
            return cache.Get<T>(key);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">缓存的项</param>
        /// <param name="acquire">没有缓存的时候获取数据的方式</param>
        /// <param name="cacheTime">单位分钟  默认30</param>
        /// <returns></returns>
        public static T Get<T>(string key, Func<T> acquire, int cacheTime = 30)
        {
            if (!cache.Contains(key))
            {
                T result = acquire.Invoke();
                cache.Add(key, result, cacheTime);
            }
            return GetData<T>(key);

            //if (cache.Contains(key))
            //{
            //    return GetData<T>(key);
            //}
            //else
            //{
            //    T result = acquire.Invoke();//执行委托  获取委托结果   作为缓存值
            //    cache.Add(key, result, cacheTime);
            //    return result;
            //}
        }

        /// <summary>
        /// 添加缓存数据。
        /// 如果另一个相同键值的数据已经存在,原数据项将被删除,新数据项被添加。
        /// </summary>
        /// <param name="key">缓存数据的键值</param>
        /// <param name="value">缓存的数据,可以为null值</param>
        /// <param name="expiratTime">缓存过期时间间隔(单位:分钟)</param>
        public static void Add(string key, object value, int expiratTime = 30)
        {
            if (Contains(key))
                cache.Remove(key);
            cache.Add(key, value, expiratTime);
        }

        /// <summary>
        /// 删除缓存数据项
        /// </summary>
        /// <param name="key"></param>
        public static void Remove(string key)
        {
            cache.Remove(key);
        }

        /// <summary>
        /// 删除所有缓存数据项
        /// </summary>
        public static void RemoveAll()
        {
            cache.RemoveAll();
        }
        /// <summary>
        /// 获取ObjectCache实例,可以进行遍历
        /// </summary>
        /// <returns></returns>
        public static ObjectCache GetCacheInstance()
        {
            return cache.GetCacheInstance();
        }
        #endregion

    }
}

ICache.cs

using System.Runtime.Caching;

namespace Common
{
    /// <summary>
    /// Cache manager interface
    /// </summary>
    public interface ICache
    {
        /// <summary>
        /// Gets or sets the value associated with the specified key.
        /// </summary>
        /// <typeparam name="T">Type</typeparam>
        /// <param name="key">The key of the value to get.</param>
        /// <returns>The value associated with the specified key.</returns>
        T Get<T>(string key);

        /// <summary>
        /// Adds the specified key and object to the cache.
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="data">Data</param>
        /// <param name="cacheTime">Cache time</param>
        void Add(string key, object data, int cacheTime = 30);

        /// <summary>
        /// Gets a value indicating whether the value associated with the specified key is cached
        /// </summary>
        /// <param name="key">key</param>
        /// <returns>Result</returns>
        bool Contains(string key);

        /// <summary>
        /// Removes the value with the specified key from the cache
        /// </summary>
        /// <param name="key">/key</param>
        void Remove(string key);

        /// <summary>
        /// Clear all cache data
        /// </summary>
        void RemoveAll();

        object this[string key] { get; set; }

        int Count { get; }

        ObjectCache GetCacheInstance();
    }
}