代码改变世界

Asp.net之缓存(一)

2009-07-19 02:31  Ecin  阅读(1070)  评论(2编辑  收藏  举报

       近段时间,发现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方法: 

                          

public void 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方法:

 

public Object 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(nullnew 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(nullnew 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(nullnew string[] { cacheKey }), System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(030), 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    }