asp.net缓存机制
一、缓存的类别
1、页面输出ASP.NET数据缓存
页面输出缓存是一种传统级别的相对简单的缓存机制。它将页面数据缓存在服务器内存中,当有客户端再次请求这些内容的时候,服务器可以直接将这些页面数据输出,直到数据缓存过期。
页面输出缓存有两种使用方法:
使用@ OutputCache指令,常见代码如:
〈%@ OutputCache Duration="60" VaryByParam="sID" Location="Any"%〉
以上例子定义了页面输出缓存有效时间为60s,60s后新建缓存;缓存版本因页面传递的sID参数不同而不同;Location="Any"指定了。
使用页面输出缓存API该方法在页面的程序部分执行,常见代码如:
Response.Cache.SetExpires(DataTime.Now.AddSeconds(60));
上句设定页面缓存有效时间为60s。
2、页面部分缓存
有时候我们可能并不希望把整个页面都缓存起来,而只是缓存页面的某个部分。常用方法有3种:
使用@ OutputCache指令
这种方法的实质是:将需要缓存的这部分内容做成用户自定义控件,然后为自定义控件设置页面缓存代码,方法同页面输出缓存。
3、应用程序数据缓存
ASP.NET数据缓存的主要功能是在内存中存储各种与应用程序相关的对象。方法有三种:
指定键和值
Cache["keyName"] = "123";
该语句将新建或者重写名称为txtName的缓存,并赋值为123。
使用Add方法
Cache.Add("keyName","123",null,DataTime.Now.AddSeconds(60),TimeSpan.Zero, CacheItemPriority.High,onRemove);
该句实现上例同样的功能,并设定其缓存依赖项为null;缓存有效时间为60s;最后一次访问所添加对象时到该对象过期时间的时间间隔为零(TimeSpan.Zero);缓存对象优先级为High;当缓存被删除时调用委托名称为onRemove。
使用Insert方法
string fileName = Server.MapPath ("file.xml");//设置文件路径 DateTime dt = DateTime.Now; //设置跟踪依赖文件的开始时间 CacheDependency dep = new CacheDependency(fileName,dt);//创建依赖对象
Insert方法和Add方法使用方法基本一致,但Insert方法还有几种自己的重载后的方法,例如:
Cache.Insert("keyName","123");
4、缓存依赖
ASP.NET数据缓存的好处很多,但他也有弊端。比如说数据的实时性,用户获取的页面可能是几十秒甚至是几个小时以前的服务器缓存信息,这一点对于实时性要求比较高的程序来说是不可容忍的。这时候我们可以通过设定缓存依赖,通过对依赖文件的更改变动情况的判断,来决定程序是否需要重建(刷新)缓存。
缓存依赖的方式有很多种,这里我们着重讲解自定义依赖缓存: 自定义缓存依赖
代码:
二、缓存使用举例
ASP.NET缓存数据技巧三则
﹤%...@ Page Language="C#" AutoEventWireup="true" CodeFile="date.aspx.cs" Inherits="date" %﹥ ﹤%...@ OutputCache Duration="60" VaryByParam="CustomerID" %﹥ ﹤!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"﹥ ﹤html xmlns="http://www.w3.org/1999/xhtml" ﹥ ﹤head runat="server"﹥ ﹤title﹥ASP.NET数据缓存﹤/title﹥ ﹤/head﹥ ﹤body﹥ 10. ﹤form id="form1" runat="server"﹥ ﹤div﹥ ﹤asp:GridView ID="GridView1" runat="server" BackColor="LightGoldenrodYellow" BorderColor="Tan" BorderWidth="1px" CellPadding="2" ForeColor="Black" GridLines="None"﹥ ﹤FooterStyle BackColor="Tan" /﹥ ﹤SelectedRowStyle BackColor="DarkSlateBlue" ForeColor="GhostWhite" /﹥ ﹤PagerStyle BackColor="PaleGoldenrod" ForeColor="DarkSlateBlue" HorizontalAlign="Center" /﹥ ﹤HeaderStyle BackColor="Tan" Font-Bold="True" /﹥ ﹤AlternatingRowStyle BackColor="PaleGoldenrod" /﹥ ﹤/asp:GridView﹥ ﹤br /﹥ ﹤br /﹥ ﹤asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/date.aspx?CustomerID=16"﹥16﹤/asp:HyperLink﹥ ﹤asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl="~/date.aspx?CustomerID=19"﹥19﹤/asp:HyperLink﹥ ﹤/div﹥ ﹤/form﹥ ﹤/body﹥ ﹤/html﹥protected void Page_Load(object sender, EventArgs e) ...{ string conn, comm, id; if (Request.QueryString["CustomerID"] == null) ...{ id = "16"; } else ...{ id = Request.QueryString["CustomerID"]; } conn = "Server=WEB\SQLEXPRESS;Uid=moon;Pwd=1qaz2wsx;Database=store"; comm = "SELECT * FROM orders WHERE CustomerID =" + id; SqlDataAdapter da = new SqlDataAdapter(comm, conn); DataSet ds = new DataSet(); da.Fill(ds); GridView1.DataSource = ds.Tables[0]; GridView1.DataBind(); Response.Write(DateTime.Now.ToString()); }
运行后分别点击16和19会根据这两个关键字SELECT出不同的数据,这时候根据我们传递的两个参数会分别建立两个缓存页,在每点击一个关键字后请记住显示的时间,再反复刷新看看时间有什么变化!好了接下来讲一下数据缓存。
ASP.NET数据缓存(Data Caching)
在System.Web.Caching空间里有一个类“Cache”我们可以通过这个类对数据进行缓存。
最简单的缓存方法:Cache["MyCacheString"] = "My CSDN BLOG!!!"; 通过赋值的形式建立一个缓存,再通过赋值的形式取出缓存:myLabel.Text = Cache["MyCacheString"].ToString();这种方法使用非常的简单可是功能上受到了一些限制,为了更完善的订制缓存,应该使用Cache.Insert()方法,下面举个例子:
页面里只需要放一下GridView就可以了
using System; using System.Web.Caching; using System.Data; using System.Data.SqlClient; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.WebuI; using System.WebuI.WebControls; using System.WebuI.WebControls.WebParts; using System.WebuI.HtmlControls; public partial class DataCache : System.WebuIpage { DataView dv;//先声明一个数据视图用来存放数据库里的数据表 protected void Page_Load(object sender, EventArgs e) { dv = (DataView)Cache["ds"];//从ASP.NET数据缓存中读取数据表 if (dv == null)//如果缓存是空的,就建立数据库连接,从数据库里读数据 { string conn, comm; conn = "Server=WEB\SQLEXPRESS;Uid=moon;Pwd=1qaz2wsx;Database=store"; comm = "SELECT * FROM orders"; SqlDataAdapter da = new SqlDataAdapter(comm, conn); DataSet ds = new DataSet(); da.Fill(ds); dv = ds.Tables[0].DefaultView; //下面这句是关键,具体参数后面介绍 Cache.Insert("ds", dv, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(3)); Databind(); Label.Text = DateTime.Now.ToString();//参考用的时间,可有可无 } else { Databind(); Response.Write("Is Cache Data!!!");//此句可有可无 } } protected void Databind()//自定义的数据绑定方法 { GridView.DataSource = dv; GridView.DataBind(); } }
ASP.NET数据缓存参数说明
Cache.Insert (String, Object, CacheDependency, DateTime, TimeSpan) 1是缓存的名称,2是缓存的数据对象,3是缓存键依赖项,通常为Null,4是过期时间,如果使用相对过期时间则设为NoAbsoluteExpiration,5是可调过期时间,如果参数4使用了固定过期时间,则此参数要设成NoSlidingExpiration。呵呵是不是看的有点晕啊,举两个具体例子说一下过期时间的问题
Cache.Insert("ds", dv, null,DateTime.Now.AddMinutes(5) , System.Web.Caching.Cache.NoSlidingExpiration);
在这个例子里当缓存建立后过5分钟就过期。
Cache.Insert("ds", dv, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(5));
这个例子里缓存建立后,过期时间为可调,比如1:20秒建立的缓存过期时间应该是6:20但如果在3:20有人访问了缓存,则过期时间将调整为8:20,以此类推……
我们在VS2005里建立一个测试看看使用缓存前和使用缓存后的性能变化吧!看到没有,没有缓存前用了0.43秒而使用缓存后只用了0.08秒性能相差5倍多啊!!!
三、ASP.NET缓存数据技巧三则
ASP.NET缓存数据技巧:访问缓存的值
由于缓存中所存储的信息为易失信息,即该信息可能由 ASP.NET 移除,因此建议先确定该项是否在缓存中。如果不在,则应将它重新添加到缓存中,然后检索该项。
string cachedString; if (Cache["CacheItem"] != null) { cachedString = (string)Cache["CacheItem"]; } else { //缓存不存在时 Cache.Insert("CacheItem", "Hello, World.") cachedString = (string)Cache["CacheItem"]; }
ASP.NET缓存数据技巧:删除缓存项
由于以下任一原因,缓存中的数据可能会自动移除:缓存已满、该项已过期、依赖项发生更改。注意:如果调用 Insert 方法,并向缓存中添加与现有项同名的项,则将从缓存中删除该旧项。显示删除缓存的值:
Cache.Remove("MyCacheKey");
ASP.NET缓存数据技巧:删除缓存项时通知应用程序
从缓存中移除项时通知应用程序,可能非常有用。例如,可能具有一个缓存的报告,创建该报告需花费大量的时间进行处理。当该报告从缓存中移除时,希望重新生成该报告,并立即将其置于缓存中,以便下次请求该报告时,用户不必等待对此报告进行处理。
ASP.NET 提供了CacheItemRemovedCallback 委托,在从缓存中移除项时能够发出通知。还提供 CacheItemRemovedReason 枚举,用于指定移除缓存项的原因。举例:假设有一个 ReportManager 对象,该对象具有两种方法,即 GetReport 和 CacheReport。GetReport 报告方法检查缓存以查看报告是否已缓存;如果没有,该方法将重新生成报告并将其缓存。CacheReport 方法具有与 CacheItemRemovedCallback 委托相同的函数签名;从缓存中移除报告时,ASP.NET 会调用 CacheReport 方法,然后将报告重新添加到缓存中。
创建一个 ASP.NET 网页,该网页将调用类中用于将项添加到缓存中的方法。
protected void Page_Load(object sender, EventArgs e) { this.Label1.Text = ReportManager.GetReport(); }
创建用于在从缓存中删除项时处理通知的完整类ReportManager。
using System; using System.Web; using System.Web.Caching; public static class ReportManager { private static bool _reportRemovedFromCache = false; static ReportManager() { } //从缓存中获取项 public static String GetReport() { lock (typeof(ReportManager)) { if (HttpContext.Current.Cache["MyReport"] != null) { //存在MyReport缓存项,返回缓存值 return (string)HttpRuntime.Cache["MyReport"]; } else { //MyReport缓存项不存在,则创建MyReport缓存项 CacheReport(); return (string)HttpRuntime.Cache["MyReport"]; } } } //将项以 MyReport 的名称添加到缓存中,并将该项设置为在添加到缓存中后一分钟过期。 //并且该方法注册 ReportRemoveCallback 方法,以便在从缓存中删除项时进行调用。 public static void CacheReport() { lock (typeof(ReportManager)) { HttpContext.Current.Cache.Add("MyReport", CreateReport(), null, DateTime.MaxValue, new TimeSpan(0, 1, 0), System.Web.Caching.CacheItemPriority.Default, ReportRemovedCallback); } } //创建报告,该报告时MyReport缓存项的值 private static string CreateReport() { System.Text.StringBuilder myReport = new System.Text.StringBuilder(); myReport.Append("Sales Report< br />"); myReport.Append("2005 Q2 Figures< br />"); myReport.Append("Sales NE Region - $2 million< br />"); myReport.Append("Sales NW Region - $4.5 million< br />"); myReport.Append("Report Generated: " + DateTime.Now.ToString() + "< br />"); myReport.Append("Report Removed From Cache: " + _reportRemovedFromCache.ToString()); return myReport.ToString(); } //当从缓存中删除项时调用该方法。 public static void ReportRemovedCallback(String key, object value, CacheItemRemovedReason removedReason) { _reportRemovedFromCache = true; CacheReport(); } }
不应在 ASP.NET 页中实现回调处理程序,因为在从缓存中删除项之前该页可能已被释放,因此用于处理回调的方法将不可用,应该在非ASP.NET的程序集中实现回调处理程序。为了确保从缓存中删除项时处理回调的方法仍然存在,请使用该方法的静态类。但是,静态类的缺点是需要保证所有静态方法都是线程安全的,所以使用lock关键字。