使用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 - 是一个简单易用的响应式图像灯箱效果 ...
随机推荐
- WampServer2.5的XDebug调试不成功的原因
WampServer2.5的php.ini文件位置很奇妙,除了在“wamp\bin\php\php5.5.12”目录下有一个外,“wamp\bin\apache\apache2.4.9\bin”目录下 ...
- HDU 1328 IBM Minus One
IBM Minus One Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- Web应用的部署
本文将介绍一些Web应用的部署: 部署规则 要成功地部署一个Web应用,必须遵循以下目录结构. 1.WEB-INF一定要直接放到应用上下文(Webapp)之下. 2.classes目录必须直接放在WE ...
- java web每天定时执行任务(四步轻松搞定)
第一步: package com.eh.util; import java.util.Calendar; import java.util.Date; import java.util.Timer; ...
- 如何截取url中的各个参数?
在页面跳的时候,目的界面可能会根据url中的某些参数进行数据处理,这个时候如何能快速并设计一个通用的截取url中的参数,并且获取各个参数值? 代码: url = location.search;//获 ...
- Javascript 可同时变大变宽等一系列效果运动框架——逐行分析代码,让你轻松了解运动的原理
等待已久的可变大,变宽 等一系列效果运动框架出炉了,现在还是个初级版本,能满足需求.我们看看是如何实现的. 我们知道在Javascript 中 ‘.’等同于 ‘[]’ 例如: oDiv.style.h ...
- c语言函数实现交换两个数的值
代码: #include <stdio.h> void swap(int x,int y) { int temp; temp = x; x = y; y = temp; printf(&q ...
- python学习day2(一)
一.上周作业回顾 1.登陆接口: 思路流程: 1.登陆,三次锁定用户 2.用户信息文件,黑名单文件 3.检测黑名单,如输入账号在黑名单中存在,不允许登陆 4.用户密码判断 主要知识点:while,fo ...
- android4.0 HttpClient 以后不能在主线程发起网络请求
android4.0以后不能在主线程发起网络请求,该异步网络请求. new Thread(new Runnable() { @Override public void run() { // TODO ...
- BeyondCompare常用功能图解
http://jingyan.baidu.com/article/066074d68f847ec3c31cb05a.html http://lovesoo.org/use-file-compariso ...