分享基于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:\app\app.config");
分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!的更多相关文章
- Go/Python/Erlang编程语言对比分析及示例 基于RabbitMQ.Client组件实现RabbitMQ可复用的 ConnectionPool(连接池) 封装一个基于NLog+NLog.Mongo的日志记录工具类LogUtil 分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!
Go/Python/Erlang编程语言对比分析及示例 本文主要是介绍Go,从语言对比分析的角度切入.之所以选择与Python.Erlang对比,是因为做为高级语言,它们语言特性上有较大的相似性, ...
- 基于AQS实现的Java并发工具类
本文主要介绍一下基于AQS实现的Java并发工具类的作用,然后简单谈一下该工具类的实现原理.其实都是AQS的相关知识,只不过在AQS上包装了一下而已.本文也是基于您在有AQS的相关知识基础上,进行讲解 ...
- Android分享到微信和朋友圈的工具类
1.只要填写上正确的app_id,且引用上该工具类你就能实现分享到朋友圈和分享到微信. 2.需要到微信平台下载jar包,以及注册一个appid import android.content.Conte ...
- 基于Druid数据库连接池的DBUtil工具类
工具类 DruidUtil.java package com.zzuli.util; import com.alibaba.druid.pool.DruidDataSourceFactory; imp ...
- 分享自己配置的HttpURLConnection请求数据工具类
>>该工具类传入string类型url返回string类型获取结果import java.io.BufferedReader;import java.io.InputStream;impo ...
- AntZipUtils【基于Ant的Zip压缩解压缩工具类】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 Android 压缩解压zip文件一般分为两种方式: 基于JDK的Zip压缩工具类 该版本存在问题:压缩时如果目录或文件名含有中文, ...
- 基于WebImage的图片上传工具类
支持缩略图和水印. using System; using System.IO; using System.Linq; using System.Web; using System.Web.Helpe ...
- 基于AFNetworking封装的网络请求工具类【原创】
今天给大家共享一个我自己封装的网络请求类,希望能帮助到大家. 前提,导入AFNetworking框架, 关于修改AFN源码:通常序列化时做对text/plan等的支持时,可以一劳永逸的修改源代码,在a ...
- 分享非常好用的前端分页js工具类 灵活 简单易懂
分享自己封装的前端分页js工具类 下面是默认样式效果截图 可以随意更改js及css 很灵活 /** * pageSize, 每页显示数 * pageIndex, 当前页数 * pageCount 总 ...
随机推荐
- 使用curl上传图片的方法
关键:当参数名为"@绝对路径",这时 CURL 會幫你做 multipart/form-data 編碼 实现方法: $params = array( 'file' => '@ ...
- org.hibernate.hql.internal.ast.QuerySyntaxException: XXX is not mapped
异常情况: 最近在把一个项目拆分多个 module 的时候数据库查询遇到这个异常:org.hibernate.hql.internal.ast.QuerySyntaxException: Identi ...
- 在Codeblocks下配置GoogleTest单元测试工具
开发工具 我和我的组员的都是使用的是大一老师推荐的codeblocks,所以,就愉快的决定了工具统一为codeblocks,语言C++. 测试单元 老师推荐的是JUnit和VSTS工具,但同学们从大一 ...
- anaconda安装opencv(python)
1.win10 win10没有安装python,只安装了anaconda,然后使用pip安装opencv-python,版本很新,opencv_python4.0.0的. 网速有点莫名其妙,时快时慢 ...
- CMS使用对应版本当作新项目。
document.form1 整体替换document.forms[0] document.Templetslist 整体替换document.forms[0] document.f_Upload整体 ...
- [转]Understanding OpenStack Authentication: Keystone PKI
The latest stable release of OpenStack, codenamed Grizzly, revolutionizes the way user authenticatio ...
- NeuChar 平台使用及开发教程(三):使用 NeuChar 的菜单服务
上一篇<NeuChar 平台使用及开发教程(二):设置平台账号>我们已经完成了平台账号的设置,下面就马上来体验一下自定义菜单的设置吧! 进入某个 Neural Cell 的设置界面,在右侧 ...
- 解决微信小程序video属性controls失效问题
<view class="VideoBox"> <video class='myVideo' id="myVideo01" src=" ...
- [Swift]LeetCode170.两数之和III - 数据结构设计 $ Two Sum III - Data structure design
Design and implement a TwoSum class. It should support the following operations:add and find. add - ...
- zookeeper实现项目初始化缓存以及同步监听
Spring-利用InitializingBean接口和zookeeper实现项目初始化缓存以及同步监听 1.先贴出几个需要用到的工具类 ZkClientUtils import com.ithzk. ...