Cache类用于web应用程序缓存。向Cache对象中添加一项有两种方法add和insert,而insert方法又有重载的几个方法。
实现目标:将访问记录存入Cache中,每隔一段时间将缓存中数据写入数据库。
实现思路:记录访问记录前,检测缓存中是否有对应项,若没有,初始化缓存,有,对缓存进行更新,并给缓存加一个委托(当缓存过期时将数据写入数据库)
实现:定义一个VisitCache类,一个Visit类,一个VisitCollection类
首先,实现Visit类,ip为访问者ip,Time为访问时间
public class Visit { public Visit() { } private string _ip; public string IP { get{return this._ip;} set{this._ip=value;} } private DateTime _time; public DateTime Time { get{return this._time;} set{this._time=value;} } }然后,实现VisitCollection类,用来存储多个Visit结点
public class VisitCollection:CollectionBase { public VisitCollection() { } public void Add(visit v) { List.Add(v); } public Visit this[int index] { get { return (Visit)this.List[index]; } } }最后定义VisitCache,实现在缓存中插入某项,更新缓存中的记录。
定义几个变量,用来实现对缓存过期进行控制,RunTime存储缓存实例化多长时间。expireTime表示缓存过期的时限。startTime存储缓存实例化起始时间。
private static DateTime startTime; private static int expireTime=30; private static VisitCollection vc; private static int runTime; private static int RunTime { get{return runTime;} set{ runTime=(int)((DateTime.Now.Ticks-startTime.Ticks)/10000000);} }当缓存不存在时,实例化缓存:
public static VisitCollection Instance(HttpContext context) { vc=(VisitCollection)context.Cache["visitTest-VisitRecord"]; if(vc==null) { CacheItemRemovedCallback onremove=new CacheItemRemovedCallback(OnRemove); vc=new VisitCollection(); vc.Clear(); startTime=DateTime.Now; context.Cache.Insert("visitTest-VisitRecord",vc,null,DateTime.Now.AddSeconds(30),TimeSpan.Zero,CacheItemPriority.High,onremove); } return vc; } public static VisitCollection Instance() { return Instance(HttpContext.Current); }当缓存存在,更新缓存内容,在用insert方法进行插入时给缓存添加一个委托:
public static void UpdateCache(Visit v) { UpdateCache(v,HttpContext.Current); } public static void UpdateCache(Visit v,HttpContext context) { Instance(context); vc.Add(v); CacheItemRemovedCallback onremove=new CacheItemRemovedCallback(OnRemove); int left=expireTime-RunTime; context.Cache.Insert("visitTest-VisitRecord",vc,null,DateTime.Now.AddSeconds(left),TimeSpan.Zero,CacheItemPriority.High,onremove); }当visitTest-VisitRecord从缓存中移除时,处理方法:
public static void OnRemove(string s,object k,System.Web.Caching.CacheItemRemovedReason reason) { if(reason.Equals(CacheItemRemovedReason.Expired)||reason.Equals(CacheItemRemovedReason.Underused)) { ArrayList list=new ArrayList(); for(int i=0;i<vc.Count;i++) { string sql="insert into visit values('"+vc[i].IP+"','"+vc[i].Time+"')"; list.Add(sql); } DataProvider.ExecuteNonQuery(list); } }其实这里需要解决几个问题:
因为利用Insert插入将用新版本覆盖旧版本的项 ,当用Insert插入时将缓存中旧项移除,然后插入新项。用Insert方法时,也会调用OnRemove进行处理,所以在OnRemove方法进行处理中要进行判断项从缓存中移除是用户插入项引起的还是由于缓存过期引起的。还有就是在更新时要获取缓存过期还剩的时间。