zoukankan      html  css  js  c++  java
  • 分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Caching;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace AutoLogisticsPH.Common.Utils
    {
        /// <summary>
        /// 基于MemoryCache(内存缓存)的缓存工具类
        /// Author:左文俊
        /// Date:2017/12/11
        /// </summary>
        public static class MemoryCacheUtil
        {
            private static readonly Object _locker = new object(), _locker2 = new object();
    
            /// <summary>
            /// 取缓存项,如果不存在则返回空
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <returns></returns>
            public static T GetCacheItem<T>(String key)
            {
                try
                {
                    return (T)MemoryCache.Default[key];
                }
                catch
                {
                    return default(T);
                }
            }
    
            /// <summary>
            /// 是否包含指定键的缓存项
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            public static bool Contains(string key)
            {
                return MemoryCache.Default.Contains(key);
            }
    
            /// <summary>
            /// 取缓存项,如果不存在则新增缓存项
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <param name="cachePopulate"></param>
            /// <param name="slidingExpiration"></param>
            /// <param name="absoluteExpiration"></param>
            /// <returns></returns>
            public static T GetOrAddCacheItem<T>(String key, Func<T> cachePopulate, TimeSpan? slidingExpiration = null, DateTime? absoluteExpiration = null)
            {
                if (String.IsNullOrWhiteSpace(key)) throw new ArgumentException("Invalid cache key");
                if (cachePopulate == null) throw new ArgumentNullException("cachePopulate");
                if (slidingExpiration == null && absoluteExpiration == null) throw new ArgumentException("Either a sliding expiration or absolute must be provided");
    
                if (MemoryCache.Default[key] == null)
                {
                    lock (_locker)
                    {
                        if (MemoryCache.Default[key] == null)
                        {
                            T cacheValue = cachePopulate();
                            if (!typeof(T).IsValueType && ((object)cacheValue) == null) //如果是引用类型且为NULL则不存缓存
                            {
                                return cacheValue;
                            }
    
                            var item = new CacheItem(key, cacheValue);
                            var policy = CreatePolicy(slidingExpiration, absoluteExpiration);
    
                            MemoryCache.Default.Add(item, policy);
                        }
                    }
                }
    
                return (T)MemoryCache.Default[key];
            }
    
            /// <summary>
            /// 取缓存项,如果不存在则新增缓存项
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <param name="cachePopulate"></param>
            /// <param name="dependencyFilePath"></param>
            /// <returns></returns>
            public static T GetOrAddCacheItem<T>(String key, Func<T> cachePopulate, string dependencyFilePath)
            {
                if (String.IsNullOrWhiteSpace(key)) throw new ArgumentException("Invalid cache key");
                if (cachePopulate == null) throw new ArgumentNullException("cachePopulate");
    
                if (MemoryCache.Default[key] == null)
                {
                    lock (_locker2)
                    {
                        if (MemoryCache.Default[key] == null)
                        {
                            T cacheValue = cachePopulate();
                            if (!typeof(T).IsValueType && ((object)cacheValue) == null) //如果是引用类型且为NULL则不存缓存
                            {
                                return cacheValue;
                            }
    
                            var item = new CacheItem(key, cacheValue);
                            var policy = CreatePolicy(dependencyFilePath);
    
                            MemoryCache.Default.Add(item, policy);
                        }
                    }
                }
    
                return (T)MemoryCache.Default[key];
            }
    
            /// <summary>
            /// 移除指定键的缓存项
            /// </summary>
            /// <param name="key"></param>
            public static void RemoveCacheItem(string key)
            {
                try
                {
                    MemoryCache.Default.Remove(key);
                }
                catch
                { }
            }
    
            private static CacheItemPolicy CreatePolicy(TimeSpan? slidingExpiration, DateTime? absoluteExpiration)
            {
                var policy = new CacheItemPolicy();
    
                if (absoluteExpiration.HasValue)
                {
                    policy.AbsoluteExpiration = absoluteExpiration.Value;
                }
                else if (slidingExpiration.HasValue)
                {
                    policy.SlidingExpiration = slidingExpiration.Value;
                }
    
                policy.Priority = CacheItemPriority.Default;
    
                return policy;
            }
    
            private static CacheItemPolicy CreatePolicy(string filePath)
            {
                CacheItemPolicy policy = new CacheItemPolicy();
                policy.ChangeMonitors.Add(new HostFileChangeMonitor(new List<string>() { filePath }));
                policy.Priority = CacheItemPriority.Default;
                return policy;
            }
        }
    }
    

    支持:可指定绝对过期时间、滑动过期明间、文件依赖  三种缓存方式,目前已在公司各种生产业务项目中有使用。优点是可以根据数据的使用频率设置缓存有效期,特别是文件依赖缓存,比如:连接字符串读取一次后,若CONFIG文件没有改变,则缓存永久有效,一旦CONFIG更改,则缓存失效需重新读取,保证数据缓存的最大可用性,减少不必要的多次重复读取CONFIG。

    使用示例很简单:(如下:会在第一次读取连接字符串并解密后返回给connstr变量,后续直接通过缓存KEY dbConnName直接返回连接字符串的结果,若修改了连接字符串的CONFIG文件,则缓存的项会失效,会重新读取连接字符串并重新加入到缓存中)
                string connstr= MemoryCacheUtil.GetOrAddCacheItem(dbConnName, () =>
                {
                    var connStrSettings = ConfigUtil.GetConnectionString(dbConnName,dbConnectionStringConfigPath);
                    string dbProdName = connStrSettings.ProviderName;
                    string dbConnStr = connStrSettings.ConnectionString;
                    return EncryptUtil.Decrypt(dbConnStr);
                }, "缓存依赖文件路路,如:c:appapp.config");

  • 相关阅读:
    线性表的实现用通用方法实现线性表的初始化、求表长、插入元素、删除元素等
    用c++定义两个坐标点,计算两点间距离;进而计算线段的面积
    Java:学生信息的录入,各种排序,对文件的操作
    数组1 2 3 4 5 6 1(输入-1结束),奇数位的数逆序,偶数位数不变
    按层次遍历二叉树,用队列作为缓冲
    Chapter09"内核模式下的线程同步"之事件内核对象
    Chapter10“I/O设备的同步和异步”之打开和关闭设备
    CSDN博客积分系统
    探秘Java垃圾回收机制
    Chapter09“内核模式下的线程同步”之可等待的计时器内核对象
  • 原文地址:https://www.cnblogs.com/zuowj/p/8440902.html
Copyright © 2011-2022 走看看