近段时间,发现web开发中缓存是个比较重要的东西,以前只是拿来用用,比如说应用程序缓存,感觉跟状态管理差不多,Cache跟Applicaition长得很像。唯一我知道的区别就是缓存容易丢失,所以在存储一些持久性变量时改用Applicaion较佳。现在又把Cache温习了下,原来是自己对原理上的东西了解得不够,技术的掌握如果抛开了原理,那么是骡子是马都分不清了。下面我写的只是对自己学习缓存一点总结,做个笔记吧。
某些情况下,为了提高应用程序性能,我们可以采用缓存机制,例如,有些网站的访问量很大,但是有的页面更新的频率不高,如果用户每次点击提交一个请求时,都要经过IIS服务器,显然,又得重新经历一次页面的生命周期,但是回发给浏览器的内容却没有变化,假说某些页面存储的数据量很大,那么用户等待时间就会很长了,这样,交互性就不是那么好了。所以,我们可以采用Asp.net缓存机制,当用户再次提交请求时,只要设置了缓存,发回服务器时直接可以将缓存的HTML页面返还给服务器,少了页面生命周期这个费时的过程,不再是经过服务器处理的页,响应时间当然会成倍提高。
在asp.net中,缓存分为两种,应用程序缓存和页面输出缓存,这次我说的是只是关于应用程序缓存的一些知识。
应用程序缓存其实很简单,可以通过编程实现。如果知道应用程序状态管理,那么理解应用程序缓存就应该不难了。应用程序缓存可以将数据以键值对的形式存储在服务器内存中,但是,跟应用程序状态又有所不同,应用程序缓存的数据是容易丢失的,数据并不是在整个应用程序生命周期内都存储在服务器内存中。当缓存项过期,无效或出现内存不足时会自动删除。不过我们可以在缓存项删除时自动通知应用程序,然后采取一些措施更新缓存项。
应用程序缓存是用System.Web.Caching命名空间下的Cache类实现的,缓存实例即Cache对象是每个应用程序专用的,并且每个应用只有一个。缓存生存期依赖于应用程序的生存期,所以重启应用程序后重新创建Cache对象,上次的缓存项将会被清空。
一.添加缓存项
1.以键值对形式添加缓存项
Cache["playerInfo"] = dataSource;
2.使用Cache类中的Insert方法或者Add方法添加缓存项
i.Insert方法:
string key,
Object value
)
public void Insert (
string key,
Object value,
CacheDependency dependencies
)
public void Insert (
string key,
Object value,
CacheDependency dependencies,
DateTime absoluteExpiration,
TimeSpan slidingExpiration
)
public void Insert (
string key,
Object value,
CacheDependency dependencies,
DateTime absoluteExpiration,
TimeSpan slidingExpiration,
CacheItemPriority priority,
CacheItemRemovedCallback onRemoveCallback
)
ii.Add方法:
string key,
Object value,
CacheDependency dependencies,
DateTime absoluteExpiration,
TimeSpan slidingExpiration,
CacheItemPriority priority,
CacheItemRemovedCallback onRemoveCallback
)
其中,对上面的参数做些说明:
- key
-
用于引用该项的缓存键。
- value
-
要添加到缓存的项。
- dependencies
-
该项的文件依赖项或缓存键依赖项。当任何依赖项更改时,该对象即无效,并从缓存中移除。如果没有依赖项,则此参数包含 空引用
- absoluteExpiration
-
所添加对象将过期并被从缓存中移除的时间。如果使用可调过期,则 absoluteExpiration 参数必须为 NoAbsoluteExpiration。
- slidingExpiration
-
最后一次访问所添加对象时与该对象过期时之间的时间间隔。如果该值等效于 20 分钟,则对象在最后一次被访问 20 分钟之后将过期并从缓存中移除。如果使用绝对过期,则 slidingExpiration 参数必须为 NoSlidingExpiration。
- priority
-
对象的相对成本,由 CacheItemPriority枚举表示。缓存在退出对象时使用该值;具有较低成本的对象在具有较高成本的对象之前被从缓存移除。
- onRemoveCallback
-
在从缓存中移除对象时所调用的委托(如果提供)。当从缓存中删除应用程序的对象时,可使用它来通知应用程序。
-
说了这么多,给段完整示例:
-
aspx页面
-
Cache示例
注:如果使用Insert方法向缓存添加项,并且已经存在预先有项同名的项,则缓存中现有项被替换,当是使用Add方法不会替换该项,也不会引发异常,故推荐使用Insert方法。
-
二.缓存依赖项
-
在asp.net缓存机制中,可以向缓存项添加依赖项,当依赖项发生更改时,缓存项就会被自动删除,起到实时更新。在应用程序缓存中,可以向Add或Insert方法传递CacheDependncy对象(或SqlDependency对象)的一个实例,以添加缓存依赖项。缓存依赖项有以下几种:
-
1.键依赖项
-
Cache.Insert("playerInfo", dataSource, new CacheDependency(null, new string[] { cacheKey }));//cacheKey为缓存依赖项的建
当cacheKey的键值更改时,缓存项就会被删除
-
2.文件依赖项
-
缓存依赖项可以依赖于一个文件,一旦文件被修改或删除,缓存项就会被删除。
-
Cache.Insert("playerInfo", dataSource, new CacheDependency(Server.MapPath("~/App_Data/PlayerInfo.xml")));
PlayerInfo.xml为一个关联的xml文件,当其发生更改时,缓存项就会被删除
-
3.SQL依赖项
-
有时候,我们需要把一个数据库里面的表缓存起来。但是,由于数据库中的记录是随表随时变化的,我们就可以为缓存项添加SQL依赖项,数据对应的表发生变化时会自动删除缓存项。通过使用SqlCacheDependency对象创建依赖于数据库表的记录。
-
当然,创建SQL缓存依赖项时必须先配置Web.config文件:
-
1 <connectionStrings>
2 <add name="NBADateConString" connectionString="Server=.;Initial Catalog=NBAData;Integrated Security=True" providerName="System.Data.SqlClient"/>
3 </connectionStrings>
4 <caching>
5 <sqlCacheDependency>
6 <databases>
7 <add name="NBAData" connectionStringName="NBADateConString"/>
8 </databases>
9 </sqlCacheDependency>
10 </caching>现在,我们就可以依赖于该连接的数据库某张表的缓存了:
-
Cache.Insert("playerInfo", dataSource, new SqlCacheDependency("NBAData", "Team"));
4.聚合依赖项
-
有时候缓存项需要依赖于多个缓存依赖项,我们就可以为其添加聚合依赖项,其实就是前面几种依赖项的集合。聚合依赖项里既可以添加依赖的缓存项的建,也可以是一个文件,也可以是SQL依赖项,可以通过System.Web.Caching.AggregateCacheDependency来添加多个依赖项。
-
CacheDependency cacheKeyDependency = new CacheDependency(null, new string[] { cacheKey });
CacheDependency fileDependency = new CacheDependency(Server.MapPath("~/App_Data/PlayerInfo.xml"));
AggregateCacheDependency acd = new AggregateCacheDependency();
acd.Add(cacheKeyDependency);
acd.Add(fileDependency);
Cache.Insert("playerInfo", dataSource, acd);三.缓存项删除时通知应用程序
-
当我们所缓存项的自动被删除或丢失时,需要通知应用程序,就可以使用CacheItemRemovedCallBack委托,缓存项删除时实现回调。其中提供的参数类型有个CacheItemRemovedReason枚举,可以指定删除缓存项的原因,下面是一完整示例:
-
HTML页面代码:
-
1<%@ Page Language="C#" AutoEventWireup="true" CodeFile="RemovedCallback.aspx.cs" Inherits="ApplicationCache_RemovedCallback" %>
2
3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
5<html xmlns="http://www.w3.org/1999/xhtml">
6<head runat="server">
7 <title>删除缓存项时提示</title>
8</head>
9<body>
10 <form id="form1" runat="server">
11 <div>
12 <asp:GridView ID="GridView1" runat="server">
13 </asp:GridView>
14
15 <br />
16 所在球队:<asp:TextBox ID="txtTeamName" runat="server"></asp:TextBox>
17 <asp:Button ID="btnUpdate" runat="server" onclick="btnUpdate_Click"
18 Text="Update" />
19 <br />
20 <asp:Label ID="lblMsg" runat="server" ForeColor="#FF66FF" Visible="False"></asp:Label>
21
22 </div>
23 </form>
24</body>
25</html> - 后台代码:
-
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Web;
5using System.Web.UI;
6using System.Web.UI.WebControls;
7using System.Web.Caching;
8
9public partial class ApplicationCache_RemovedCallback : System.Web.UI.Page
10{
11 protected void Page_Load(object sender, EventArgs e)
12 {
13 TeamInfo team = Cache["teamInfo"] as TeamInfo;
14 if (team==null)
15 {
16 team = new TeamInfo("火箭队");
17 Cache["teamInfo"] = team;
18 }
19
20 BindData("teamInfo");
21 txtTeamName.Text = team.TeamName;
22
23 }
24 public void BindData(string cacheKey)
25 {
26 List<PlayerInfo> dataSource = Cache["playerInfo"] as List<PlayerInfo>;
27
28 if (dataSource==null)
29 {
30 PlayerInfo YaoMing = new PlayerInfo("姚明", "中锋", "2.03cm", "101.0Kg");
31 PlayerInfo Microred = new PlayerInfo("Microred", "unknown", "unknown", "unknown");
32 dataSource = new List<PlayerInfo>();
33 dataSource.Add(YaoMing);
34 dataSource.Add(Microred);
35
36 Cache.Insert("playerInfo", dataSource, new CacheDependency(null, new string[] { cacheKey }), System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 3, 0), CacheItemPriority.High, new CacheItemRemovedCallback(RemovedCallback));
37
38 }
39
40 GridView1.DataSource = dataSource;
41 GridView1.DataBind();
42
43 }
44 protected void btnUpdate_Click(object sender, EventArgs e)
45 {
46 if (Cache["teamInfo"]!=null)
47 {
48 TeamInfo team = Cache["teamInfo"] as TeamInfo;
49 team.TeamName = txtTeamName.Text;
50 Cache["teamInfo"] = team;
51 }
52 }
53
54 public void RemovedCallback(string key, object value, CacheItemRemovedReason reason)
55 {
56 lblMsg.Visible = true;
57 lblMsg.Text = "缓存删除原因:" + reason.ToString();
58 Page.ClientScript.RegisterStartupScript(this.GetType(), "cacheMsg", "window.alert('缓存依赖已更新')", true);
59 }