定义 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 ...
- HTML5实现刮奖效果
原文:HTML5实现刮奖效果 要实现刮奖效果,最重要的是要找到一种方法:当刮开上层的涂层是就能看到下层的结果.而HTML5的canvas API中有一个属性globalCompositeOperati ...
- React实践(一)
该实践取自官方教程:https://github.com/reactjs/react-tutorial 主要是自实现的过程以及一些心得体会 该实践是实现一个评论框. 一个展示所有评论的视图 一个提交评 ...
- hdu 3449 (有依赖的01背包)
依赖背包 事实上,这是一种树形DP,其特点是每个父节点都需要对它的各个儿子的属性进行一次DP以求得自己的相关属性. fj打算去买一些东西,在那之前,他需要一些盒子去装他打算要买的不同的物品.每一个盒子 ...
- SimpleInjector与MVC4集成,与Web Api集成,以及通过属性注入演示
SimpleInjector与MVC4集成,与Web Api集成,以及通过属性注入演示 1,与MVC集成 见http://simpleinjector.codeplex.com/wikipage? ...
- 在LINQ中实现多条件联合主键LEFT JOIN
我昨天遇到一个LINQ下使用多条件比对产生LEFT JOIN的问题,经过深入研究,终于解决了,也让我学到了新的东西,特地拿来分享. 实例:有一张库存异常变更视图KCYD,仓库ID[Ckid]和物品ID ...
- json 解析解乱码
1. 该法的字符编码: 串店txt文档文档都有自己的编码,例如utf-8,ansi等待,但当 存款txt文件.其编码将和txt编码文件本身一致. 例如,之前的字符编码ansi.txt该文件的编码是u ...
- C--控制语句循环例子
C的三种循环while.for和do while 先说一下scanf()函数的返回值问题 当scanf("%d,%d",&a,&b);如果用户正确输入了俩个整形变 ...
- HammerDB数据库压力工具使用简略步骤
欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/38879681 HammerDB数据库压力工具使用简略步骤 尽管没有图,可是文字 ...
- visual studio 辅助工具
resharper 这是一个收费软件 需要下载对应版本的注册机. 效果如图所示: 这里的using 很多没有用到,他会用灰色标记,你都可以统统去掉. 声明一个类 ,要求 首字母大写,如果你小写了,他 ...