随笔 - 64, 文章 - 0, 评论 - 370, 引用 - 12
数据加载中……

.NET中的缓存

构建高性能的应用程序的非常重要一项就是使用缓存。使用缓存可以避免重新从读取服务器端读取数据,节省数据从客户端到服务器间往返的时间,同时也减轻了服务器数据存取的压力。如果客户端非常频繁地读取服务器上的数据,比如生成报表,并且服务器每次获取这些数据都经过复杂的处理逻辑,那么就可能非常有必要使用缓存。应用程序需要.NET2.0中提供了两种不同方式的缓存:页面输出缓存应用程序数据缓存 

页面输出缓存

我们知道asp.net服务器控件每次生成数据都要经过一个复杂的生存周期过程,参见[服务器端控件页面生存周期]。使用页面输出缓存就是指内存中缓存asp.net页面的内容,这样每次需要这些内容都无需重新生成,取而代之的是从内存中直接读取,这样节省了asp.net页面控件生成这些内容的时间,从而大大地提高了应用程序的性能。如果客户访问的这些页面的内容不经常变化,这些页面的访问量较大,那么就非常适宜使用页面输出缓存。

我们可以设置两种不同类型的页面输出缓存:全局页面缓存页面片断缓存。全局页面缓存是指将整个页面的内容都缓存在内存中供客户端调用。而页面片断缓存是指在内存中缓存部分页面的内容,而其他的部分是动态重新生成的。

页面片断缓存有一种较为特殊的情形是,除了页面的某一局部内容不进行缓存,其他整个页面是缓存起来的,这种情形叫做Post-Cache Substitution。比如,登陆后在页面某个部分显示用户名处,我们就有可能用到这种情形。

 使用页面输出缓存

可以通过两种方式设置使用缓存。

通过web.config配置缓存如下:
<System.web>

         <caching>

                <outputCache enableOutputCache="true"

                 enableFragmentCache="true"

                 sendCacheControlHeader="true"

                 omitVaryStar="false">

                </outputCache>

         <caching>

</system.web>

在页面中配置使用缓存如下:
 

如何从缓存中读取数据

要从缓存中读取数据,需要先判断一下缓存的键值是否存在,因为缓存中存储的信息是不稳定的,可能它已经被ASP.NET移去。因此推荐采用如下方式读取缓存的内容:

string cachedString;

if (Cache["CacheItem"] != null)

{

    cachedString = (string)Cache["CacheItem"];

}

else

{

    Cache.Insert("CacheItem", "Hello, World.");

    cachedString = (string)Cache["CacheItem"];

}

 

全局页面缓存 

下面例子表示缓存时间10秒,就是说每隔10秒读取一次系统时间。

VaryByParam参数的一点说明:

VaryByParam 属性功能十分强大,它允许用户控件作者指示 ASP.NET 在服务器上缓存/存储输出缓存区域的多个实例。例如,前一个用户控件的宿主页的下列 URL 缓存用户控件内容的单独实例。

http://localhost/mypage.aspx?categoryid=foo&selectedid=0
http://localhost/mypage.aspx?categoryid=foo&selectedid=1

用户控件内的逻辑因此能够根据提供的参数动态生成不同的内容(单独缓存)。

除了支持 VaryByParam 属性外,片段缓存还支持 VaryByControl 属性。VaryByParam 属性基于使用 POST GET 发送的名称/值对改变缓存结果,而 VaryByControl 属性则通过用户控件中的控件改变缓存片段。例如:

<%@ OutputCache Duration="120" VaryByParam="none" VaryByControl="Category" %>

注意:与输出缓存页相似,即使不使用 VaryByParam,也要求显式使用它。

例如,下列指令指示 ASP.NET 输出缓存用户控件 120 秒,并使用“CategoryID”“SelectedID”查询字符串或窗体发布参数改变缓存。

<%@ OutputCache Duration="120" VaryByParam="CategoryID;SelectedID"%>

示例代码:

<%@ Page Language="C#" %>

<%@ OutputCache Duration="10" VaryByParam="*"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server"> 

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

    <title>Untitled Page</title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

    <%Response.Write(System.DateTime.Now);%>

    </div>

    </form>

</body>

</html>

 

页面片断缓存

设置页面片断缓存可以采用<%@ Control Language="C#" ClassName="WebUserControl" %>

或者在类名前加特性[PartialCaching(3)]

如:

<%@ Control Language="C#" ClassName="WebUserControl" %>

<%@ OutputCache Duration="10" VaryByParam="*"%>

<script runat="server">

    protected void Page_Load(object sender, EventArgs e)

    {

        this.Label1.Text = System.DateTime.Now.ToString("hh:mm:ss");

        this.timer.Style.Add("width", (DateTime.Now.Second * 4).ToString() + "px");

    }

</script>

<div id = "timer" runat="server" style="background-color:Cyan;">

<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>

</div>

或,

[PartialCaching(3)]

public partial class WebUserControl3 : System.Web.UI.UserControl

{

    protected void Page_Load(object sender, EventArgs e)

    {

        this.Label1.Text = System.DateTime.Now.ToString("hh:mm:ss");

        this.timer.Style.Add("width", (DateTime.Now.Second * 4).ToString() + "px");

    }

}

 

应用程序数据缓存

ASP.NET 提供一个功能完整的缓存引擎,页面可使用该引擎通过 HTTP 请求存储和检索任意对象。ASP.NET 缓存对于每个应用程序是私有的并且将对象存储在内存中。缓存的生存期与应用程序的生存期相同,也就是说,当应用程序重新启动时,将重新创建缓存。

缓存提供了简单的词典接口,使程序员可以轻松地将对象放到缓存中以及从缓存中检索对象。在最简单的情况下,将某项放到缓存中就像向词典中添加一个词条一样。

对于需要更复杂功能的应用程序,ASP.NET 缓存支持清理、过期、文件依赖项和键依赖项。

· 清理是指当内存变得很少时,缓存尝试移除不常使用和不太重要的项。希望控制清理如何发生的程序员可以在项插入到缓存时为清理程序提供提示,指出创建项的相对成本和使项保持有用而必须具有的相对访问率。

· 过期使程序员得以提供缓存项的生存期,其时间既可以是确切时间(例如,6:00 过期),也可以是相对于项的上次使用的时间(例如,上次访问项后 20 分钟过期)。项过期后将从缓存中被移除,以后若试图检索它,将返回空值,除非将它重新插入缓存。

· 文件和键依赖项允许缓存项的有效性基于外部文件或其他缓存项。如果依赖项改变,则缓存项失效并从缓存中被移除。有关如何使用此功能的示例,请考虑下列方案:应用程序从定期更新的 XML 文件中读取财务信息。应用程序处理文件中的数据并以可使用的格式创建表示该数据的对象图形。应用程序缓存该数据并在从中读取该数据的文件上插入依赖项。当更新该文件时,数据从缓存中被移除,应用程序可以重新读取它并重新插入该数据的更新副本。

示例,建立一个缓存xml文件的应用程序如下[下载源代码http://files.cnblogs.com/Ring1981/Cache.rar]:

1. 建立default.aspx页面

<%@ Page Trace="true" TraceMode="SortByCategory" Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

 

<!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>Untitled Page</title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

        <asp:Button ID="Button1" runat="server" Text="Flush Cache" OnClick="Button1_Click" />

    <asp:DataGrid ID="dg1" runat="server"/>

    </div>

    </form>

</body>

</html>

 

2. 添加一个names.xml

<?xml version="1.0" encoding="utf-8" ?>

<people>

 <person first="Scott" last="stafield"></person>

 <person first="jim" last="Green"></person>

 <person first="kate" last="Green"></person>

</people>

3.添加后台代码

 using System;

using System.Data;

using System.Configuration;

using System.Collections;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

using System.Data;

using System.Web.Caching;

 

public partial class _Default : System.Web.UI.Page

{

    protected void Page_Load(object sender, EventArgs e)

    {

        if (!Page.IsPostBack)

        {

            DataSet ds = null;

            ds = (DataSet)Cache["names"];

 

            if (ds == null)

            {

                string path = @"c:\inetpub\wwwroot\Cache\names.xml";

                ds = new DataSet();

                ds.ReadXml(path);

 

                CacheDependency cd = new CacheDependency(path);

                Cache.Insert("names", ds, cd);

                Trace.Warn("Names read from XML file");

            }

            else

            {

                Trace.Warn("Names read from cache");

            }

            dg1.DataSource = ds;

            dg1.DataBind();

        }

    }

    protected void Button1_Click(object sender, EventArgs e)

    {
       Cache.Remove("names");

        Response.Redirect("default.aspx");

    }
}

运行程序, 第一次运行时,DataGrid里的数据是从xml文件中读取的。 以后每次刷新,文件都是从缓存读取的。 我们可以从每次运行时间看到,每次读取xml文件花费时间大约0.001275s,而每次读取缓存花费时间大约0.000044 可见读取缓存数据性能能够大大地改善。

Category

Message

From First(s)

From Last(s)

Names read from XML file

0.00155997480126664

0.001275

Names read from cache

0.000343619091253218

0.000044


使用数据库缓存:

待续... 


参考文件:

MSDN 文档
Microsoft ASP.NET 入门教: http://chs.gotdotnet.com/quickstart/aspplus/doc/quickstart.aspx 
Scott stafield先生的视频教程

posted on 2007-04-10 10:13 Ring 阅读(1449) 评论(1)  编辑 收藏 所属分类: B .Net 开发

评论

#1楼    回复  引用  查看    

缓存可以很大的提高系统性能的
2007-03-20 12:45 | JesseZhao      

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  博客园首页

  新闻频道

  社区

  小组

  博问

  网摘

  闪存

  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
成果网帮您增加网站收入


相关链接: