定义 ICache 接口,以及实现默认的 ASP.NET 缓存机制
本文定义 ICache 接口,以及实现默认的 ASP.NET 缓存机制(即通过 System.Web.Caching.Cache)来缓存,将来也可以通过扩展,替换默认实现。
下面直接贴代码了:
ICache 接口
基础接口 - ICache
using System;
using System.Collections;
using System.Collections.Generic; public interface ICache
{
void Clear();
bool Contains(string key);
object Get(object key);
T Get<T>(object key);
IList<CacheItemDescriptor> GetDescriptors();
T GetOrInsert<T>(object key, int timeToLiveInSeconds, bool slidingExpiration, Func<T> fetcher);
void Insert(object key, object value);
void Insert(object key, object value, int timeToLive, bool slidingExpiration);
void Insert(object key, object value, int timeToLive, bool slidingExpiration, CacheItemPriority priority);
void Remove(object key);
void RemoveAll(ICollection keys); int Count { get; } ICollection Keys { get; }
}
结束标记。
CacheAspNet
依赖 Web 运行时的缓存
using System;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Caching; public class CacheAspNet : ICache
{
private Cache _cache;
private CacheSettings _settings; public CacheAspNet()
{
this._settings = new CacheSettings();
this.Init(new CacheSettings());
} public CacheAspNet(CacheSettings settings)
{
this._settings = new CacheSettings();
this.Init(settings);
} private string BuildKey(object key)
{
if (this._settings.UsePrefix) return (this._settings.PrefixForCacheKeys + "." + key.ToString());
return key.ToString();
} public void Clear()
{
ICollection keys = this.Keys;
foreach (string str in keys)
{
string key = this.BuildKey(str);
this._cache.Remove(key);
}
} public bool Contains(string key)
{
string str = this.BuildKey(key);
if (this._cache.Get(str) == null) return false;
return true;
} private System.Web.Caching.CacheItemPriority ConvertToAspNetPriority(CacheItemPriority priority)
{
if (priority == CacheItemPriority.Normal) return System.Web.Caching.CacheItemPriority.Normal;
if (priority == CacheItemPriority.High) return System.Web.Caching.CacheItemPriority.High;
if (priority == CacheItemPriority.Low) return System.Web.Caching.CacheItemPriority.Low;
if (priority == CacheItemPriority.Normal) return System.Web.Caching.CacheItemPriority.Normal;
return System.Web.Caching.CacheItemPriority.NotRemovable;
} public T Get<T>(object key)
{
string str = this.BuildKey(key);
object obj2 = this._cache.Get(str);
if (obj2 == null) return default(T);
return (T) obj2;
} public object Get(object key)
{
string str = this.BuildKey(key);
return this._cache.Get(str);
} public IList<CacheItemDescriptor> GetDescriptors()
{
IList<CacheItemDescriptor> list = new List<CacheItemDescriptor>();
IEnumerator enumerator = this.Keys.GetEnumerator();
while (enumerator.MoveNext())
{
string current = enumerator.Current as string;
object obj2 = this.Get(current);
list.Add(new CacheItemDescriptor(current, obj2.GetType().FullName));
}
((List<CacheItemDescriptor>) list).Sort((Comparison<CacheItemDescriptor>) ((c1, c2) => c1.Key.CompareTo(c2.Key)));
return list;
} public T GetOrInsert<T>(object key, int timeToLiveInSeconds, bool slidingExpiration, Func<T> fetcher)
{
object obj2 = this.Get(key);
if (obj2 == null)
{
T local = fetcher();
this.Insert(key, local, timeToLiveInSeconds, slidingExpiration);
return local;
}
return (T) obj2;
} private void Init(CacheSettings settings)
{
this._cache = HttpRuntime.Cache;
this._settings = settings;
} public void Insert(object key, object value)
{
this.Insert(key, value, this._settings.DefaultTimeToLive, this._settings.DefaultSlidingExpirationEnabled, this._settings.DefaultCachePriority);
} public void Insert(object key, object value, int timeToLive, bool slidingExpiration)
{
this.Insert(key, value, timeToLive, slidingExpiration, this._settings.DefaultCachePriority);
} public void Insert(object keyName, object value, int timeToLive, bool slidingExpiration, CacheItemPriority priority)
{
TimeSpan span = TimeSpan.FromSeconds((double) timeToLive);
if (keyName == null)
{
throw new ArgumentNullException("keyName");
}
if(TimeSpan.Zero > span)
{
throw new ArgumentException("timeToLive");
}
System.Web.Caching.CacheItemPriority priority2 = this.ConvertToAspNetPriority(priority);
string key = this.BuildKey(keyName);
if (TimeSpan.Zero < span)
{
if (slidingExpiration)
{
this._cache.Insert(key, value, null, Cache.NoAbsoluteExpiration, span, priority2, null);
}
else
{
DateTime absoluteExpiration = DateTime.Now.AddSeconds((double)timeToLive);
this._cache.Insert(key, value, null, absoluteExpiration, Cache.NoSlidingExpiration, priority2, null);
}
}
else
{
this._cache.Insert(key, value, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, priority2, null);
}
} public void Remove(object key)
{
string str = this.BuildKey(key);
this._cache.Remove(str);
} public void RemoveAll(ICollection keys)
{
foreach (object obj2 in keys)
{
string key = this.BuildKey((string) obj2);
this._cache.Remove(key);
}
} public int Count
{
get
{
if (!this._settings.UsePrefix) return this._cache.Count;
int num = ;
foreach (DictionaryEntry entry in this._cache)
{
string key = (string) entry.Key;
if (key.StartsWith(this._settings.PrefixForCacheKeys))
{
num++;
}
}
return num;
}
} public ICollection Keys
{
get
{
IList<string> list = new List<string>();
foreach (DictionaryEntry entry in this._cache)
{
string key = (string) entry.Key;
if (!this._settings.UsePrefix)
{
list.Add(key);
}
else if (key.StartsWith(this._settings.PrefixForCacheKeys))
{
list.Add(key.Substring(this._settings.PrefixForCacheKeys.Length + ));
}
}
return (list as ICollection);
}
} public CacheSettings Settings
{
get
{
return this._settings;
}
}
}
CacheItemPriority.cs
using System; public enum CacheItemPriority
{
Default = ,
High = ,
Low = ,
Normal = ,
NotRemovable =
}
CacheItemDescriptor.cs
using System; public class CacheItemDescriptor
{
private string _key;
private string _serializedData;
private string _type; public CacheItemDescriptor(string key, string type) : this(key, type, string.Empty)
{
} public CacheItemDescriptor(string key, string type, string serializedData)
{
this._serializedData = string.Empty;
this._key = key;
this._type = type;
this._serializedData = serializedData;
} public string Data
{
get
{
return this._serializedData;
}
} public string ItemType
{
get
{
return this._type;
}
} public string Key
{
get
{
return this._key;
}
}
}
CacheSettings.cs
using System; public class CacheSettings
{
public CacheItemPriority DefaultCachePriority = CacheItemPriority.Normal;
public bool DefaultSlidingExpirationEnabled = false;
public int DefaultTimeToLive = ;
public string PrefixForCacheKeys = "cmnlib";
public bool UsePrefix = true;
}
Cacher.cs
using System;
using System.Collections;
using System.Collections.Generic; public class Cacher
{
private static ICache _provider = new CacheAspNet(); public static void Clear()
{
_provider.Clear();
} public static bool Contains(string key)
{
return _provider.Contains(key);
} public static object Get(object key)
{
return _provider.Get(key);
} public static T Get<T>(object key)
{
return _provider.Get<T>(key);
} public static T Get<T>(string key, int timeInSeconds, Func<T> fetcher)
{
return Get<T>(key, true, timeInSeconds, false, fetcher);
} public static T Get<T>(string key, TimeSpan timeInSeconds, Func<T> fetcher)
{
return Get<T>(key, true, timeInSeconds.Seconds, false, fetcher);
} public static T Get<T>(string key, bool useCache, TimeSpan timeInSeconds, Func<T> fetcher)
{
return Get<T>(key, useCache, timeInSeconds.Seconds, false, fetcher);
} public static T Get<T>(string key, bool useCache, int timeInSeconds, bool slidingExpiration, Func<T> fetcher)
{
if (!useCache) return fetcher();
return _provider.GetOrInsert<T>(key, timeInSeconds, slidingExpiration, fetcher);
} public static IList<CacheItemDescriptor> GetDescriptors()
{
return _provider.GetDescriptors();
} public static void Init(ICache cacheProvider)
{
_provider = cacheProvider;
} public static void Insert(object key, object value)
{
_provider.Insert(key, value);
} public static void Insert(object key, object value, int timeToLive, bool slidingExpiration)
{
_provider.Insert(key, value, timeToLive, slidingExpiration);
} public static void Insert(object key, object value, int timeToLive, bool slidingExpiration, CacheItemPriority priority)
{
_provider.Insert(key, value, timeToLive, slidingExpiration, priority);
} public static void Remove(object key)
{
_provider.Remove(key);
} public static void RemoveAll(ICollection keys)
{
_provider.RemoveAll(keys);
} public static int Count
{
get
{
return _provider.Count;
}
} public static ICollection Keys
{
get
{
return _provider.Keys;
}
} public static ICache Provider
{
get
{
return _provider;
}
}
}
结束标记。
RuntimeMomoryCache
备注:.NET 4.0 增加了一个 System.Runtime.Caching.Momory 类,不依赖 Web。
代码如下:
public class RuntimeMemoryCache : ICache
{
// Fields
private readonly MemoryCache _cache = MemoryCache.Default; // Methods
public void Add(string key, object value, TimeSpan timeSpan)
{
if (!string.IsNullOrEmpty(key) && value != null) this._cache.Add(key, value, DateTimeOffset.Now.Add(timeSpan), null);
} public void AddWithFileDependency(string key, object value, string fullFileNameOfFileDependency)
{
if (!string.IsNullOrEmpty(key) && value != null)
{
CacheItemPolicy policy = new CacheItemPolicy {
AbsoluteExpiration = DateTimeOffset.Now.AddMonths()
};
policy.ChangeMonitors.Add(new HostFileChangeMonitor(new List<string> { fullFileNameOfFileDependency }));
this._cache.Add(key, value, policy, null);
}
} public void Clear()
{
foreach (string str in this._cache.AsParallel<KeyValuePair<string, object>>().ToDictionary<KeyValuePair<string, object>, string>(a => a.Key).Keys)
{
this._cache.Remove(str, null);
}
} public object Get(string cacheKey)
{
return this._cache[cacheKey];
} public void MarkDeletion(string key, object value, TimeSpan timeSpan)
{
this.Remove(key);
} public void Remove(string cacheKey)
{
this._cache.Remove(cacheKey, null);
} public void Set(string key, object value, TimeSpan timeSpan)
{
this._cache.Set(key, value, DateTimeOffset.Now.Add(timeSpan), null);
}
}
结束标记。
分布式缓存 - Memcached
利用 Memcached 实现分布式缓存。
MemcachedClient 使用的是 Enyim.Caching。开源地址:https://github.com/enyim/EnyimMemcached
public class MemcachedCache : ICache
{
// Fields
private MemcachedClient cache = new MemcachedClient(); // Methods
public void Add(string key, object value, TimeSpan timeSpan)
{
key = key.ToLower();
this.cache.Store(, key, value, DateTime.Now.Add(timeSpan));
} public void AddWithFileDependency(string key, object value, string fullFileNameOfFileDependency)
{
this.Add(key, value, new TimeSpan(, , , ));
} public void Clear()
{
this.cache.FlushAll();
} public object Get(string cacheKey)
{
cacheKey = cacheKey.ToLower();
HttpContext current = HttpContext.Current;
if (current != null && current.Items.Contains(cacheKey)) return current.Items[cacheKey];
object obj2 = this.cache.Get(cacheKey);
if (current != null && obj2 != null) current.Items[cacheKey] = obj2;
return obj2;
} public Dictionary<string, Dictionary<string, string>> GetStatistics()
{
throw new NotImplementedException();
} public void MarkDeletion(string key, object value, TimeSpan timeSpan)
{
this.Set(key, value, timeSpan);
} public void Remove(string cacheKey)
{
cacheKey = cacheKey.ToLower();
this.cache.Remove(cacheKey);
} public void Set(string key, object value, TimeSpan timeSpan)
{
this.Add(key, value, timeSpan);
}
}
谢谢浏览!
定义 ICache 接口,以及实现默认的 ASP.NET 缓存机制的更多相关文章
- 概述ASP.NET缓存机制
PetShop之ASP.NET缓存机制 如果对微型计算机硬件系统有足够的了解,那么我们对于Cache这个名词一定是耳熟能详的.在CPU以及主板的芯片中,都引入了这种名为高速缓冲存储器(Cache)的技 ...
- 学习ASP.NET缓存机制
缓存是大型BS架构网站的性能优化通用手段,之前知道有这个概念,并且也知道很重要,但是一直没静下心来了解.这次借着学习PetShop源码的机会熟悉一下ASP.NET基本的缓存机制(生产环境中的真实缓存有 ...
- 详解ASP.NET缓存机制
文中对ASP.NET的缓存机制进行了简述,ASP.NET中的缓存极大的简化了开发人员的使用,如果使用得当,程序性能会有客观的提升.缓存是在内存存储数据的一项技术,也是ASP.NET中提供的重要特性之一 ...
- java中接口的定义和接口的实现
1.接口的定义 使用interface来定义一个接口.接口定义同类的定义类似,也是分为接口的声明和接口体,其中接口体由常量定义和方法定义两部分组成.定义接口的基本格式如下: [修饰符] interfa ...
- [二] java8 函数式接口详解 函数接口详解 lambda表达式 匿名函数 方法引用使用含义 函数式接口实例 如何定义函数式接口
函数式接口详细定义 package java.lang; import java.lang.annotation.*; /** * An informative annotation type use ...
- JDK8.0接口中的默认方法和静态方法
我们在接口中通常定义的方法是抽象方法,即没有方法体,只有返回值类型和方法名:(public abstract) void Method(); 类在实现接口的时候必须重写抽象方法才可以 jdk8中新加的 ...
- C++:如何正确的定义一个接口类
C++中如何定义接口类?首先给接口类下了定义:接口类应该是只提供方法声明,而自身不提供方法定义的抽象类.接口类自身不能实例化,接口类的方法定义/实现只能由接口类的子类来完成. 而对于C++,其接口类一 ...
- Java8新特性_接口中的默认方法
默认方法由来猜想 1. Collection接口.Collections公共类. 同是操作集合,为啥要搞俩?没必要.在接口中搞一些默认实现,一个接口即搞定了. 2. Java8支持Lambda表达式 ...
- Java 8 接口中的默认方法与静态方法
Java 8 接口中的默认方法与静态方法 1. 接口中的默认方法 允许接口中包含具有具体实现的方法,该方法称"默认方法",默认方法使用用 default 关键字修饰. public ...
随机推荐
- XML概要
早在两年前,我一直听说XML,但是,只是没有时间去研究它.也不知道它的作用,花了一些时间最近几天来学习他们的语言.是XML的一些简介希望能对各位同学有所帮助: XML是eXtensible Ma ...
- Winform 实现像菜单一样弹出层
原文:Winform 实现像菜单一样弹出层 在实际工作中,如果能像菜单一样弹出自定义内容,会方便很多,比如查询时,比如下拉列表显示多列信息时,比如在填写某个信息需要查看一些信息树时.这个时候自定义弹出 ...
- 兼容Firefox和IE的onpropertychange事件oninput
原文 兼容Firefox和IE的onpropertychange事件oninput onpropertychange能够捕获每次输入值的变化.例如:对象的value值被改变时,onpropertych ...
- Apache conf文件配置个人总结
其实说到conf文件的配置,网上那必定是大堆大堆的,故今儿写着篇小博文,也只是做个总结,至于分享的价值吗,如果对屏幕前的你有用,我也很乐意啦. 首先,我们要找到Apache安装目录,我的是Ap ...
- HDU 4932 Miaomiao's Geometry(推理)
HDU 4932 Miaomiao's Geometry pid=4932" target="_blank" style="">题目链接 题意: ...
- 归并排序 & 快速排序
归并排序 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有 ...
- Android 4.4 沉浸式透明状态栏与导航栏
Android 系统自4.2 開始 UI 上就没多大改变,4.4 也仅仅是添加了透明状态栏与导航栏的功能,如图 那么如今我就来给大家解说下怎样使用这个新特性,让你的 app 尾随潮流,当然假设你不在乎 ...
- EasyUi TreeGrid封装
礼物一:树型实体的抽象与封装 所谓树型实体,就是具有树型结构关系的实体,比如省.市.区.对于初学者,可能会创建三张表进行存储,有经验的开发者通过引入ParentId将设计简化为一张表,但是基于Pare ...
- 设置CentOS开机连接网络 Centos 开机启动网卡的设置方法
我们开机网卡不能启动所以只能使用 ifup eth0 (eth0指的网卡) 来启动了,但是每一次都这样感觉不方便希望开机自动启动网卡 后来百度搜索了一下发现可以通过修改网卡( ifcfg-eth0)参 ...
- Android超炫日期日历控件:TimesSquare
先看效果图: 使用说明: 在布局文件里: <com.squareup.timessquare.CalendarPickerView android:id="@+id/calendar_ ...