分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!

简介:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
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:\app\app.config");

本文转自 梦在旅途 博客园博客,原文链接:http://www.cnblogs.com/zuowj/p/8440902.html  ,如需转载请自行联系原作者

相关文章
|
消息中间件 Linux
Linux:进程间通信(共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)
通过上述讲解和代码示例,您可以理解和实现Linux系统中的进程间通信机制,包括共享内存、消息队列和信号量。这些机制在实际开发中非常重要,能够提高系统的并发处理能力和数据通信效率。希望本文能为您的学习和开发提供实用的指导和帮助。
1107 20
|
缓存 API C#
C# 一分钟浅谈:GraphQL 中的缓存策略
本文介绍了在现代 Web 应用中,随着数据复杂度的增加,GraphQL 作为一种更灵活的数据查询语言的重要性,以及如何通过缓存策略优化其性能。文章详细探讨了客户端缓存、网络层缓存和服务器端缓存的实现方法,并提供了 C# 示例代码,帮助开发者理解和应用这些技术。同时,文中还讨论了缓存设计中的常见问题及解决方案,如缓存键设计、缓存失效策略等,旨在提升应用的响应速度和稳定性。
296 13
|
开发框架 .NET PHP
网站应用项目如何选择阿里云服务器实例规格+内存+CPU+带宽+操作系统等配置
对于使用阿里云服务器的搭建网站的用户来说,面对众多可选的实例规格和配置选项,我们应该如何做出最佳选择,以最大化业务效益并控制成本,成为大家比较关注的问题,如果实例、内存、CPU、带宽等配置选择不合适,可能会影响到自己业务在云服务器上的计算性能及后期运营状况,本文将详细解析企业在搭建网站应用项目时选购阿里云服务器应考虑的一些因素,以供参考。
|
缓存 NoSQL Java
瑞吉外卖项目笔记+踩坑2——缓存、读写分离优化
缓存菜品、套餐数据、mysql主从复制实现读写分离、前后端分离
瑞吉外卖项目笔记+踩坑2——缓存、读写分离优化
|
缓存 开发框架 .NET
看看 Asp.net core Webapi 项目如何优雅地使用内存缓存
看看 Asp.net core Webapi 项目如何优雅地使用内存缓存
394 1
|
缓存 开发框架 移动开发
uni-app:下载使用uni&创建项目&和小程序链接&数据缓存&小程序打包 (一)
uni-app 是一个跨平台的开发框架,它允许开发者使用 Vue.js 来构建应用程序,并能够同时发布到多个平台,如微信小程序、支付宝小程序、H5、App(通过DCloud的打包服务)等。uni-app 的目标是通过统一的代码库,简化多平台开发过程,提高开发效率。 在这一部分中,我们将逐步介绍如何下载和使用uni-app、创建一个新的项目、如何将项目链接到小程序,以及实现数据缓存的基本方法。
685 0
|
设计模式 存储 安全
Java面试题:设计一个线程安全的单例类并解释其内存占用情况?使用Java多线程工具类实现一个高效的线程池,并解释其背后的原理。结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
Java面试题:设计一个线程安全的单例类并解释其内存占用情况?使用Java多线程工具类实现一个高效的线程池,并解释其背后的原理。结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
500 1
|
缓存 NoSQL Redis
【Azure Redis 缓存】C#程序是否有对应的方式来优化并缩短由于 Redis 维护造成的不可访问的时间
【Azure Redis 缓存】C#程序是否有对应的方式来优化并缩短由于 Redis 维护造成的不可访问的时间
198 0
|
存储 缓存 开发框架
看看 Asp.net core Webapi 项目如何优雅地使用分布式缓存
看看 Asp.net core Webapi 项目如何优雅地使用分布式缓存
353 0
|
缓存 Java Spring
Guava缓存工具类封装和使用
Guava缓存工具类封装和使用
538 0