定义 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 ...
随机推荐
- hdu Write a simple HTML Browser
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1088 对比输出 代码: #include <stdio.h> #include <s ...
- Linux内核和根文件系统引导加载程序
续博文<u-boot之u-boot-2009.11启动过程分析> Linux内核启动及文件系统载入过程 当u-boot開始运行bootcmd命令.就进入Linux内核启动阶段,与u-boo ...
- Sql使用视图(简单的视图)适合入门-level
创建以便从库更好的数据呼叫和一个数据库,以(例如,该209东东库转移205图书馆) 例:209图书馆有不同的库名:数据库(AIS20140417092531电影库)供应商表(t_Supplier ). ...
- Moq 和RhinoMocks
Moq & RhinoMocks 使用Mock对象进行测试一般都会有以下三个关键步骤: 使用接口来描述需要测试的对象 为实际的产品代码实现这个接口 以测试为目的,在Mock对象中实现这个接口 ...
- Tomcat剖析(二):一个简单的Servlet服务器
Tomcat剖析(二):一个简单的Servlet服务器 1. Tomcat剖析(一):一个简单的Web服务器 2. Tomcat剖析(二):一个简单的Servlet服务器 3. Tomcat剖析(三) ...
- linux_Ubuntu 12.04 安装jdk
1.下载jdk6jdk6下载地址为:http://download.java.net/jdk6/,根据操作系统的选择对应的安装包,我的是ubuntu 12.04 32bit的,所以下载的文件是jdk- ...
- 解决VS 于 致命错误 RC1015: 无法打开包含文件 'afxres.h' 问题
在试验VS2010当一个问题困扰了我,它是开放的c++项目达产后,rc的dialog入口.您不能拖动控制,让我疯狂... 而最有发言权的是在线Directions问题. .题明显不是这个问题. 于是我 ...
- 【百度地图API】除夕夜,大家一起来赶走“夕”——删除标注功能
原文:[百度地图API]除夕夜,大家一起来赶走"夕"--删除标注功能 任务描述: 农历12月31日是中国传统的节日——除夕.你知道除夕是怎么来的麼? “夕”在中国古代神话中,可是一 ...
- 深入理解PHP中赋值与引用
原文:深入理解PHP中赋值与引用 先看下面的问题: <?php $a = 10;//将常量值赋给变量,会为a分配内存空间 $b = $a;//变量赋值给变量,是不是copy了一份副本,b也分配了 ...
- JVM截至多少线程可以创建: unable to create new native thread
最近的测试需要很长的连接server.这些数据需要达到100W长连接,试client.一个线程来保持连接.查找linuxserver创建者默认3200当多个线程.这个错误将得到"java.l ...