使用ConcurrentDictionary实现轻量缓存
项目中需要用到一个轻量缓存,存储重复使用的数据。
在设计中需要考虑:
1.做成通用组件,为未来其他模块方法操作结果做准备。
2.缓存模块需要接口化,为未来替换使用外部缓存做准备。
3.使用默认缓存过期时间,单个Key的过期时间可以自由配置。
使用ConcurrentDictionary来作为我们的缓存容器,并能保证线程安全。
public interface IDataCache
{
TimeSpan Ttl
{
get;
} void Set(string key, object value); void Set(string key, object value, TimeSpan ttl); object Get(string key); void PurgeExpiredEntries();
}
/// <summary>
/// An implementation of <see cref="IDataCache"/> which uses a dictionary to cache values in memory.
/// </summary>
public class InMemDataCache:IDataCache
{
private static readonly TimeSpan DefaultTtl = TimeSpan.FromMinutes(10); private readonly TimeSpan _ttl;
private readonly ConcurrentDictionary<string, CacheEntry> _cache = new ConcurrentDictionary<string, CacheEntry>(); /// <summary>
/// Initialize a new instance of <see cref="InMemDataCache"/> using the default TTL.
/// </summary>
public InMemDataCache()
: this(DefaultTtl)
{ } /// <summary>
/// Initialize a new instance of <see cref="InMemDataCache"/> using a specified TTL.
/// </summary>
/// <param name="ttl">
/// The time-to-live (TTL) of value saved into the cache. Zero or negative value indicates that values shall never expire.
/// </param>
public InMemDataCache(TimeSpan ttl)
{
_ttl = ttl;
} /// <summary>
/// The time-to-live (TTL) of value saved into the cache.
/// </summary>
public TimeSpan Ttl
{
get
{
return _ttl;
}
} /// <summary>
/// Save a key-value pair into the cache using the global TTL settings.
/// Existed value associated with the specified key shall be overwritten.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void Set(string key, object value)
{
Set(key, value, _ttl);
} /// <summary>
/// Save a key-value pair into the cache using the global TTL settings.
/// Existed value associated with the specified key shall be overwritten.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="ttl">
/// The time-to-live (TTL) of value saved into the cache. Zero or negative value indicates that values shall never expire.
/// </param>
public void Set(string key, object value, TimeSpan ttl)
{
var expirationTime = ttl <= TimeSpan.Zero ? DateTime.MinValue : DateTime.Now.Add(ttl);
var result = new CacheEntry(value, expirationTime);
_cache.AddOrUpdate(key, result, (k, o) => result);
} public object Get(string key)
{
CacheEntry entry;
if (!_cache.TryGetValue(key, out entry))
{
return null;
} if (entry.ExpirationTime == DateTime.MinValue || DateTime.Now < entry.ExpirationTime)
{
return entry.Value;
} CacheEntry old;
_cache.TryRemove(key, out old);
return null;
} public void PurgeExpiredEntries()
{
foreach (var key in _cache.Keys)
{
Get(key);
}
} private class CacheEntry
{
public readonly object Value;
public readonly DateTime ExpirationTime; public CacheEntry(object value, DateTime expirationTime)
{
// TODO: Complete member initialization
Value = value;
ExpirationTime = expirationTime;
}
}
}
完整demo路径:http://files.cnblogs.com/files/Nicolas-wang/Examples.Cache.zip
使用ConcurrentDictionary实现轻量缓存的更多相关文章
- Android轻量缓存框架--ASimpleCache
[转] 大神真面目 稀土掘金,这是一个针对技术开发者的一个应用,你可以在掘金上获取最新最优质的技术干货,不仅仅是Android知识.前端.后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过! ...
- 一种简单,轻量,灵活的C#对象转Json对象的方案
简单,是因为只有一个类 轻量,是因为整个类代码只有300行 灵活,是因为扩展方式只需要继承重写某个方法即可 补充:修正无法处理可空值类型的bug 首先我将这个类称之为JsonBuilder,我希望它以 ...
- 一种简单,轻量,灵活的C#对象转Json对象的方案(续)
本文参考资料 一种简单,轻量,灵活的C#对象转Json对象的方案 [源码]Literacy 快速反射读写对象属性,字段 一段废话 之前我已经介绍了这个方案的名称为JsonBuilder,这套方案最大的 ...
- 编写轻量ajax组件01-对比webform平台上的各种实现方式
前言 Asp.net WebForm 和 Asp.net MVC(简称MVC) 都是基于Asp.net的web开发框架,两者有很大的区别,其中一个就是MVC更加注重http本质,而WebForm试图屏 ...
- 推荐一个简单、轻量、功能非常强大的C#/ASP.NET定时任务执行管理器组件–FluentScheduler定时器
在C#WINFORM或者是ASP.NET的WEB应用程序中,根据各种定时任务的需求,比如:每天的数据统计,每小时刷新系统缓存等等,这个时候我们得应用到定时器这个东东. .NET Framework有自 ...
- CYQ.Data 轻量数据层之路 优雅V1.4 现世 附API帮助文档(九)
继上一版本V1.3版本发布到现在,时隔N天了:[V1.3版本开源见:CYQ.Data 轻量数据层之路 华丽V1.3版本 框架开源] N天的时间,根据各路网友的反映及自身的想法,继续修改优化着本框架,力 ...
- 轻量型ORM框架Dapper的使用
在真实的项目开发中,可能有些人比较喜欢写SQL语句,但是对于EF这种ORM框架比较排斥,那么轻量型的Dapper就是一个不错的选择,即让你写sql语句了,有进行了关系对象映射.其实对于EF吧,我说下我 ...
- OWIN轻量型框架介绍
OWIN轻量型框架介绍 阅读目录 引言 框架的特色 如何启动 各项功能 静态路由的3种写法 伪静态路由的支持 处理Form表单提交的文件 流式处理Post请求的数据 多种请求类型自动识别 响应处理 请 ...
- 轻量高效的开源JavaScript插件和库 【转】
图片 布局 轮播图 弹出层 音频视频 编辑器 字符串 表单 存储 动画 时间 其它 加载器 构建工具 测试 包管理器 CDN 图片 baguetteBox.js - 是一个简单易用的响应式图像灯箱效果 ...
随机推荐
- C# 利用反射动态调用类成员
用反射动态调用类成员,需要Type类的一个方法:InvokeMember.对该方法的声明如下(摘抄于MSDN): publicobject InvokeMember( string name, ...
- 解决IE6下a标签的onclick事件里的超链接不跳转问题
今天遇到个很诡异的问题,就是<a href="javascript:void(0);" onclick="window.location=url"> ...
- python排序(冒泡, 快速)
之前用java时学习的一些基础算法,今天在python上也研究下. 1. 冒泡排序 算法步骤: 50 30 70 90 10 1)50 跟 30 比不用交换. 2)步数+1, 30 跟70比 ...
- OpenGL ES 三种类型 uniform attribute varying
1.uniform变量 uniform变量是外部application程序传递给(vertex和fragment)shader的变量.因此它是application通过函数glUniform**()函 ...
- 本地拦截genymotion或者Android模拟器的网络请求
我们在主机上面运行了Burp或者fiddler,那么代理已经监听在本机的8080端口了. 那么我们需要在模拟器中进行如下设置: 1.在设置中,长按当前连接的wifi网络,弹出如下: 2. 点击修改网络 ...
- 可爱的 Python : Python中的函数式编程,第三部分
英文原文:Charming Python: Functional programming in Python, Part 3,翻译:开源中国 摘要: 作者David Mertz在其文章<可爱的 ...
- linux下监视进程 崩溃挂掉后自动重启的shell脚本
如何保证服务一直运行?如何保证即使服务挂掉了也能自动重启?在写服务程序时经常会碰到这样的问题.在Linux系统中,强大的shell就可以很灵活的处理这样的事务. 下面的shell通过一个while-d ...
- Linux下查找最大文件
当我们应用一段时间以后,Linux可能会变得臃肿了,那么,怎么找出一个“path”下的最大文件呢? 可以使用du命令,如: du -sh [dirname|filename] 如:当前目录的大小: d ...
- Android手机自带内部存储路径的获取 (转)
转自:http://my.oschina.net/liucundong/blog/288183 我有一台中兴的Android手机,型号是 ZTE U930HD,手机没有插入外置SD卡(也就是Micro ...
- aix puppet agent
demo控制脚本tel,150 5519 8367 Running Puppet on AIX Puppet on AIX is… not officially supported, yet stil ...