[索引页]
[×××]



温故知新ASP.NET 2.0(C#)(4) - Cache&SqlCacheDependency(缓存和SqlCacheDependency特性)


作者: webabcd


介绍
存是在计算中广泛使用的一种技术,通过将经常访问的数据或存取开销较大的数据保留在内存或硬盘中来提高性能。在 Web 应用程序的上下文中,缓存用于在 HTTP 请求之间保留页或数据,在重用它们时可以不必耗费资源重新创建。


关键
1、@OutputCache指令中的属性:
    Duration - 缓存时间(秒)
    VaryByParam - 根据使用 POST 或 GET 发送的名称/值对来改变缓存的结果(多参数用分号隔开)
    VaryByControl - 根据用户控件中的控件来改变缓存的片段(值是控件ID,多控件用分号隔开)
    CacheProfile - 调用配置文件中设置的缓存时间

2、增加数据缓存时用Cache.Insert,可以指定缓存时间

3、替换缓存(Substitution)- 回调函数要是静态的

4、SqlCacheDependency
配置文件中的配置
<system.web>
        <caching>
            <sqlCacheDependency enabled="true" pollTime="轮询时间(毫秒)">
                <databases>
                    <add name="名字" connectionStringName="连接字符串的名字" />
                </databases>
            </sqlCacheDependency>
            <!-- 如果是SqlServer2005的话,则只需如下设置,因为SqlServer支持基于通知的缓存失效
            <sqlCacheDependency enabled="true" />
            -->
        </caching>
    </system.web>
 
如果不是SqlServer2005的话,应该使用aspnet_regsql注册一下
aspnet_regsql.exe -S "server" -E -d "database" -ed
aspnet_regsql.exe -S "server" -E -d "database" -et -t "table"
如果是Sql验证的话要把-E换成,-U(用户名),-P(密码)


示例
页面输出缓存
Cahce/Page.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Page.aspx.cs"
        Inherits="Cahce_Page" Title="页面输出缓存" %>

<%@ OutputCache Duration="10" VaryByParam="none" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
        <p>
                Duration="10" VaryByParam="none"
        </p>
        <p>
                <%=DateTime.Now %>
        </p>
</asp:Content>
 
API操作缓存
Cahce/Page.aspx.cs
InBlock.gif using System;
InBlock.gif using System.Data;
InBlock.gif using System.Configuration;
InBlock.gif using System.Collections;
InBlock.gif using System.Web;
InBlock.gif using System.Web.Security;
InBlock.gif using System.Web.UI;
InBlock.gif using System.Web.UI.WebControls;
InBlock.gif using System.Web.UI.WebControls.WebParts;
InBlock.gif using System.Web.UI.HtmlControls;
InBlock.gif
InBlock.gif public partial class Cahce_Page : System.Web.UI.Page
InBlock.gif{
InBlock.gif         protected void Page_Load( object sender, EventArgs e)
InBlock.gif        {
InBlock.gif                 /* 通过API设置缓存 不常用啊
InBlock.gif                
InBlock.gif                // 相当于@OutputCache指令中的Duration属性
InBlock.gif                Response.Cache.SetExpires(DateTime.Now.AddSeconds(10));
InBlock.gif                // 以指定响应能由客户端和共享(代理)缓存进行缓存。
InBlock.gif                Response.Cache.SetCacheability(HttpCacheability.Public);
InBlock.gif
InBlock.gif                // 过期时间可调
InBlock.gif                Response.Cache.SetSlidingExpiration(true);
InBlock.gif                
InBlock.gif                */

InBlock.gif        }
InBlock.gif}
 
页面输出缓存(VaryByParam)
Cahce/PageByParam.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="PageByParam.aspx.cs"
        Inherits="Cahce_PageByParam" Title="页面输出缓存(VaryByParam)" %>

<%@ OutputCache CacheProfile="CacheTest" VaryByParam="p1;p2" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
        <p>
                CacheProfile="CacheTest" VaryByParam="p1;p2"
                <br />
                CacheProfile="CacheTest" - 从web.config中读信息
                <br />
                get或post方式都行
        </p>
        <p>
                <a href="?p1=a&p2=b">第一组</a>
                <br />
                <a href="?p1=c&p2=d">第二组</a>
                <br />
                <a href="?p1=e&p2=f">第三组</a>
        </p>
        <p>
                <%=DateTime.Now %>
        </p>
</asp:Content>
 
上面页所需的web.config中的配置
<system.web>
        <caching>
            <outputCacheSettings>
                <outputCacheProfiles>
                    <add name="CacheTest" duration="10" />
                </outputCacheProfiles>
            </outputCacheSettings>
        </caching>
    </system.web>
 
页面输出缓存(VaryByControl)
Cahce/CacheControl.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CacheControl.ascx.cs"
        Inherits="Cahce_CacheControl" %>
<%@ OutputCache Duration="10" VaryByControl="DropDownList1" %>
<p>
        <%=DateTime.Now %>
</p>
<p>
        <asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="XmlDataSource1"
                DataTextField="text" DataValueField="value">
        </asp:DropDownList><asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="~/Config/DropDownListData.xml">
        </asp:XmlDataSource>
</p>
<p>
        <asp:Button ID="btn" runat="Server" Text="提交" />
</p>
 
Cahce/PageByControl.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="PageByControl.aspx.cs"
        Inherits="Cahce_PageByControl" Title="页面输出缓存(VaryByControl)" %>

<%@ Register Src="CacheControl.ascx" TagName="CacheControl" TagPrefix="uc1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
        <p>
                未经缓存设置的容器页:
                <%=DateTime.Now %>
        </p>
        <p>
                经过VaryByControl设置的用户控件,根据DropDownList的不同缓存不同的内容(用户控件中的@OutputCache指令为Duration="10"
                VaryByControl="DropDownList1"):<br />
                <uc1:CacheControl ID="CacheControl1" runat="server" />
        </p>
</asp:Content>
 
数据缓存
Cahce/Data.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Data.aspx.cs"
        Inherits="Cahce_Data" Title="数据缓存" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
        <p>
                <asp:Label ID="lbl" runat="server" />
        </p>
</asp:Content>
 
Cahce/Data.aspx.cs
InBlock.gif using System;
InBlock.gif using System.Data;
InBlock.gif using System.Configuration;
InBlock.gif using System.Collections;
InBlock.gif using System.Web;
InBlock.gif using System.Web.Security;
InBlock.gif using System.Web.UI;
InBlock.gif using System.Web.UI.WebControls;
InBlock.gif using System.Web.UI.WebControls.WebParts;
InBlock.gif using System.Web.UI.HtmlControls;
InBlock.gif
InBlock.gif public partial class Cahce_Data : System.Web.UI.Page
InBlock.gif{
InBlock.gif         protected void Page_Load( object sender, EventArgs e)
InBlock.gif        {
InBlock.gif                 // 一看就懂
InBlock.gif                 if (Cache[ "key"] == null)
InBlock.gif                {
InBlock.gif                        Cache.Insert( "key", DateTime.Now, null, DateTime.Now.AddSeconds(10), TimeSpan.Zero);
InBlock.gif                }
InBlock.gif
InBlock.gif                DateTime dt = (DateTime)Cache[ "key"];
InBlock.gif                lbl.Text = dt.ToString();
InBlock.gif        }
InBlock.gif}
 
替换缓存(部分区域强行不使用缓存)
Cahce/Substitution.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Substitution.aspx.cs"
        Inherits="Cahce_Substitution" Title="替换缓存(部分区域强行不使用缓存)" %>

<%@ OutputCache Duration="10" VaryByParam="none" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
        <p>
                Duration="10" VaryByParam="none"
        </p>
        <p>
                <%=DateTime.Now %>
        </p>
        <p>
                API 向返回当前日期的静态方法中插入动态回调,此回调在每次请求时都会执行<br />
                <% Response.WriteSubstitution(new HttpResponseSubstitutionCallback(GetTime)); %>
        </p>
        <p>
                使用Substitution 控件插入动态内容<br />
                <asp:Substitution ID="Substitution1" runat="server" MethodName="GetTime" />
        </p>
</asp:Content>
 
Cahce/Substitution.aspx.cs
InBlock.gif using System;
InBlock.gif using System.Data;
InBlock.gif using System.Configuration;
InBlock.gif using System.Collections;
InBlock.gif using System.Web;
InBlock.gif using System.Web.Security;
InBlock.gif using System.Web.UI;
InBlock.gif using System.Web.UI.WebControls;
InBlock.gif using System.Web.UI.WebControls.WebParts;
InBlock.gif using System.Web.UI.HtmlControls;
InBlock.gif
InBlock.gif public partial class Cahce_Substitution : System.Web.UI.Page
InBlock.gif{
InBlock.gif         protected void Page_Load( object sender, EventArgs e)
InBlock.gif        {
InBlock.gif
InBlock.gif        }
InBlock.gif
InBlock.gif         // 回调函数所调的静态方法
InBlock.gif         public static string GetTime(HttpContext context)
InBlock.gif        {
InBlock.gif                 return DateTime.Now.ToString();
InBlock.gif        }
InBlock.gif}
 
SqlCacheDependency
页的Sql缓存
Cahce/SqlCachePage.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="SqlCachePage.aspx.cs"
        Inherits="Cahce_SqlCachePage" Title="页的Sql缓存" %>

<%@ OutputCache Duration="999999" SqlDependency="VS2005_Test:sqlcache" VaryByParam="none" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
        <p>
                Duration="999999" SqlDependency="VS2005_Test:sqlcache" VaryByParam="none"<br />
                如果是SqlServer2005则改成SqlDependency="CommandNotification<br />
                注意配置文件中的配置
        </p>
        <p>
                <%=DateTime.Now %>
        </p>
</asp:Content>
 
数据源控件的Sql缓存
Cahce/SqlCachePage.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="SqlCacheDataSourceControl.aspx.cs"
        Inherits="Cahce_SqlCacheDataSourceControl" Title="数据源控件的Sql缓存" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
        <p>
                DataSource控件设置如下属性:EnableCaching="True" SqlCacheDependency="VS2005_Test:sqlcache"
                CacheDuration="Infinite"<br />
                如果是SqlServer2005则改成SqlDependency="CommandNotification<br />
                注意配置文件中的配置
        </p>
        <p>
                <%=DateTime.Now %>
        </p>
        <p>
                <asp:SqlDataSource ID="SqlDataSource1" runat="server" EnableCaching="True" SqlCacheDependency="VS2005_Test:sqlcache"
                        CacheDuration="Infinite" ConnectionString="<%$ ConnectionStrings:SqlConnectionString %>"
                        SelectCommand="SELECT * FROM [SqlCache]"></asp:SqlDataSource>
                <asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1" AllowSorting="True">
                </asp:GridView>
        </p>
</asp:Content>
 
web.config中的相关配置
<connectionStrings>
        <add name="SqlConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\VS2005_Test.mdf;Integrated Security=True;User Instance=True"
            providerName="System.Data.SqlClient" />
    </connectionStrings>
    <system.web>
        <caching>
            <sqlCacheDependency enabled="true" pollTime="10000">
                <databases>
                    <add name="VS2005_Test" connectionStringName="SqlConnectionString" />
                </databases>
            </sqlCacheDependency>
            <!-- 如果是SqlServer2005的话,则只需如下设置,因为SqlServer支持基于通知的缓存失效
            <sqlCacheDependency enabled="true" />
            -->
        </caching>
    </system.web>
 
注意
Sql Server 2005 基于通知的缓存失效,不用aspnet_regsql设置,要设置属性SqlDependency="CommandNotification"。在首次执行某 SQL 查询之前,必须在应用程序某处调用 System.Data.SqlClient.SqlDependency.Start() 方法。此方法应放在 global.asax 文件的 Application_Start() 事件中。因为Sql Server 2005 基于通知的缓存失效对支持查询通知的查询语法有许多限制,所以我觉得最好先别用,而是使用轮询机制。在使用轮询机制时如本例子中的SqlCacheDependency="VS2005_Test:sqlcache",冒号前面是配置文件中配置的相关值指向数据库连接,后面是启用SqlCache的表名,注意区分大小写。


OK
[×××]