分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 网页技术

Asp.Net 基础知识回顾_Cache

发布时间:2023-09-06 01:47责任编辑:沈小雨关键词:暂无标签

一、传统缓存方式

比如将可重复利用的东西放到Application或是Session中去保存。

 Session["Count"] = 100;

 Application["Count"] = 100;

二、页面输出缓存

页面输出缓存是最为简单的缓存机制,该机制将整个ASP.NET页面内容保存在服务器内存中。当用户请求该页面时,系统从内存中输出相关数据,直到缓存数据过期。在这个过程中,缓存内容直接发送给用户,而不必再次经过页面处理生命周期。通常情况下,页面输出缓存对于那些包含不需要经常修改内容,需要大量处理才能编译完成的页面特别有用。需要注意的是,页面输出缓存是将页面全部内容都保存在内存中,并用于完成客户端请求。

设置页面输出缓存可以使用以下两种方式:一种是使用@OutputCache指令,另一种是使用页面输出缓存API。页面输出缓存API主要是指HttpCachePolicy类。

@ OutputCache以声明的方式控制 ASP.NET 页或页中包含的用户控件的输出缓存策略。

语法如下:

<%@ OutputCache Duration="#ofseconds" ??Location="Any | Client | Downstream | Server | None | ServerAndClient " ??Shared="True | False" ??VaryByControl="controlname" ??VaryByCustom="browser | customstring" ??VaryByHeader="headers" ??VaryByParam="parametername" ???CacheProfile="cache profile name | ‘‘" ??NoStore="true | false" ??SqlDependency="database/table name pair | CommandNotification"%>

Duration

页或用户控件进行缓存的时间(以秒计)。在页或用户控件上设置该属性为来自对象的 HTTP 响应建立了一个过期策略,并将自动缓存页或用户控件输出。

Location

用于指定输出缓存项的位置。其属性值是OutputCacheLocation枚举值,它们是Any、Client、Downstream、None、Server和ServerAndClient。默认值是Any,表示输出缓存可用于所有请求,包括客户端浏览器、代理服务器或处理请求的服务器上。需要注意的是,包含在用户控件中的@OutputCache指令不支持此属性。

Shared

一个布尔值,确定用户控件输出是否可以由多个页共享。默认值为 false。

NoStore

该属性定义一个布尔值,用于决定是否阻止敏感信息的二级存储。需要注意的是,包含在用户控件中的
@OutputCache指令不支持此属性。

SqlDependency

    提供了这样一种能力:当被监测的数据库中的数据发生变化时,SqlDependency会自动触发OnChange事件来通知应用程序,从而达到让系统自动更新数据(或缓存)的目的。

VaryByControl

该属性使用一个分号分隔的字符串列表,来更改用户控件的输出缓存。这些字符串代表在用户控件中声明的ASP.NET服务器控件的ID属性值。除非已经包含了VaryByParam属性,否则在@ OutputCache指令中,该属性是必需的。

VaryByCustom

用于自定义输出缓存要求的任意文本。如果赋予该属性值是browser,缓存将随浏览器名称和主要版本信息的不同而异。如果输入了自定义字符串,则必须在应用程序的Global.asax文件中重写HttpApplication.GetVaryByCustomString方法。

VaryByHeader

该属性中包含由分号分隔的HTTP标头列表,用于使输出缓存发生变化。当将该属性设为多标头时,对于每个指定的标头,输出缓存都包含一个请求文档的不同版本。VaryByHeader属性在所有HTTP 1.1缓存中启用缓存项,而不仅限于ASP.NET缓存。用户控件中的@ OutputCache指令不支持此属性。

三、页面输出缓存API

Response类的Cache属性用于获取页面缓存策略,Cache属性的核心是调用System.Web.HttpCachePolicy。主要用于设置缓存特定的HTTP标头的方法和用于控制ASP.NET页面输出缓存的方法。由于HttpCachePolicy类方法众多,下面简要说明几个常用方法。

SetExpires

用于设置缓存过期的绝对时间。它的参数是一个DataTime类的实例,表示过期的绝对时间。

SetLastModified

用于设置页面的Last-Modified HTTP标头。Last-Modified HTTP标头表示页面上次修改时间,缓存将依靠它来进行计时。如果违反了缓存限制层次结构,此方法将失败。该方法的参数是一个DataTime类的实例。

SetSlidingExpiration 

该方法将缓存过期从绝对时间设置为可调时间。其参数是一个布尔值。当参数为true时,Cache-Control HTTP标头将随每个响应而更新。当参数为false时,将保留该设置,且任何启用可调整过期的尝试都将静态失败。此方法不直接映射到HTTP标头,它由后续模块或辅助请求来设置源服务器缓存策略。

SetCacheability

用于设置页面的Cache-Control HTTP标头。该标头用于控制在网络上缓存文档的方式。该方法有两种重载方式,所不同的是参数。一种重载方法的参数是HttpCacheability枚举值,包括NoCache、Private、Public、Server、ServerAndNoCache和ServerAndPrivate。另一种方法的参数有两个,一个参数是HttpCacheability枚举值,另一个参数是字符串,表示添加到标头的缓存控制扩展。需要注意的是,仅当与Private或NoCache指令一起使用时,字段扩展名才有效。如果组合不兼容的指令和扩展,则此方法将引发无效参数异常。

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));

Response.Cache.SetExpires(DateTime.Parse("6:00:00PM"));

Response类的Cache属性用于获取页面缓存策略。该属性的数据类型是HttpCachePolicy。可通过调用Response.Cache来获取HttpCachePolicy实例,进而实现对于当前页面输出缓存的设置。如上代码所示,第一行代码表示输出缓存时间是60秒,并且页面不随任何GET或POST参数改变,等同于“<%@ OutputCache Duration="60" VaryByParam="none" %>”。第二行代码设置缓存过期的绝对时间是当日下午6时整。

四、页面部分缓存

有时缓存整个页面是不现实的,因为页的某些部分可能在每次请求时都需要变化。在这些情况下,只能缓存页的一部分。顾名思义,页面部分缓存是将页面部分内容保存在内存中以便响应用户请求,而页面其他部分内容则为动态内容。在页面中经常存在某些部分固定不变(如导航栏,页面右侧的排行榜等信息),而其他内容则需要根据用户请求的不同动态生成。所以我们可以将固定部分的内容缓存在服务器内存中,以减少服务器查询数据时间。

页面部分缓存也称为控件缓存,这种方式允许将需要缓存的信息包含在一个用户控件内。然后,将该用户控件标记为可缓存的,以此来缓存页面输出的部分内容。这种方式允许缓存页面中的特定内容,而不缓存整个页面。例如,如果要创建一个显示大量动态内容(如股票信息)的页,其中有些部分为静态内容(如每周总结),这时可以将静态部分放在用户控件中,并允许缓存这些内容。

页面部分缓存示例如下: 

在CacheControl.ascx的页头代码中添加声明语句:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="CacheControl.ascx.cs" Inherits="CacheControl" %>

  <%@ OutputCache Duration="60" VaryByParam="none" %>

<%=DateTime.Now %>  

调用该控件的页面代码:

 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CacheDemo.aspx.cs"%><%@ Register src="CacheControl.ascx" tagname="CacheControl" tagprefix="uc" %><head runat="server"> ???<title>CacheDemo</title></head><body> ???<form id="form1" runat="server"> ???页面的时间:<%=DateTime.Now %> <br/> ?控件的时间:<uc:CacheControl ID="CacheControl" runat="server" /><br/> ???</form></body> </html>

当刷新页面时,“页面的时间”每次刷新都变化,而“控件的时间”的数据却是60秒才变化一次。说明对页面的“局部”控件实现了缓存,而页面其它部分不受影响。

五、 应用程序数据缓存

应用程序数据缓存提供了一种编程方式,可通过键/值对将任意数据存储在内存中。使用应用程序缓存与使用应用程序状态类似。但是,与应用程序状态不同的是,应用程序数据缓存中的数据是易失的,即数据并不是在整个应用程序生命周期中都存储在内存中。应用程序数据缓存的优点是由ASP.NET管理缓存,它会在项过期、无效,或内存不足时移除缓存中的项。还可以配置应用程序缓存,以便在移除项时通知应用程序。

如下所示插入一个字符串进缓存:

Cache["name"]="CacheDemo";

这个存储的字串值可以像这样得到:

if (Cache["name"] != null){string name = Cache["name"].ToString();}

六、 缓存依赖

前文的几种方式都可以实现数据缓存功能,但问题是数据有时候是在变化的。这样用户可能在缓存期间查询的数据就是过期的数据,从而导致数据的不一致。那有没有办法在数据变化时,系统能自动更新缓存中的数据,从而让用户得到实时有效的数据。

.NET已经为我们提供了这样一种非常好的解决方法:SqlCacheDependency数据库缓存依赖。下面就让我们看一下如何实现数据库缓存依赖功能:

1. 配置SqlCacheDependency 

修改web.config,让项目启用SqlCacheDependency。

<?xml version="1.0"?><configuration> ???<appSettings/> ???<connectionStrings> ???????<add name="strcodematic" connectionString="data source=dbserver;initial catalog=codematic;user id=sa;password=sa" ?providerName="System.Data.SqlClient" /> ???</connectionStrings> ???<system.web> ???????<caching> ???????????<sqlCacheDependency enabled="true" pollTime="6000"> ???????????????<databases> <add name="codematic" connectionStringName="strcodematic" /> ???????????????</databases> ???????????</sqlCacheDependency> ????????????????</caching> ?????<compilation debug="true"> ???????</compilation> ????????????<authentication mode="Windows"/> ???????</system.web></configuration> 

注意:在<databases>节的<add name="codematic" connectionStringName="strcodematic" />中的name属性值必须和第三步的Page_Load代码中System.Web.Caching.SqlCacheDependency("codematic", "P_Product"); 中的第一个参数(数据库名称)相一致。

这里的connectionStringName指定了在<connectionStrings>中添加的某一个连接字符串。name则是为该SqlCacheDependency起的名字,这个名字将在第三步中用到。

SqlCacheDependency类会自动完成对此配置节信息的读取,以建立和数据库之间的联系。

2.启用缓存依赖

如果要启用SqlCacheDependency,则需要以命令行的方式执行。

aspnet_regsql.exe工具位于Windows\\Microsoft.NET\\Framework\\[版本]文件夹中。

aspnet_regsql -C "data source=.;initial catalog=codematic;user id=sa;password=123456" -ed -et -t "BookInfo"

参数-C后面的字符串是连接字符串(请替换成自己所需要的值),参数-t后面的字符串是数据表的名字。

 运行结果如图所示:

命令执行后,在指定的数据库中会多出一个AspNet_SqlCacheTablesForChangeNotification表。

要使得7.0或者2000版本以上的SQLServer支持SqlCacheDependency特性,需要对数据库服务器执行相关的配置。

有两种方法配置SQLServer:

一 使用aspnet_regsql命令行工具。

二 使用SqlCacheDependencyAdmin类。(msdn看到的,没用过)

例如:

aspnet_regsql -S "server" -E -d "database" –ed

或者

aspnet_regsql -S "server" -E -d "database" -et -t "table"

如果是Sql验证的话要把-E换成,-U (用户名),-P (密码)

以下是该工具的命令参数说明:

-? 显示该工具的帮助功能;

-S 后接的参数为数据库服务器的名称或者IP地址;

-U 后接的参数为数据库的登陆用户名;

-P 后接的参数为数据库的登陆密码;

-E 使用当前登录用户的 Windows 集成认证进行身份验证;

-d 后接参数为对哪一个数据库采用SqlCacheDependency功能;

-C 连接数据库的连接字符串。如果您指定服务器(-S)和登录(-U和-P,或 -E)信息,则此选项不是必需的,因为连接字符串已经包含这些信息;
-t 后接参数为对哪一个表采用SqlCacheDependency功能;
-ed 允许对数据库使用SqlCacheDependency功能;
-dd 禁止对数据库采用SqlCacheDependency功能;
-et 允许对数据表采用SqlCacheDependency功能;
-dt 禁止对数据表采用SqlCacheDependency功能;
-lt 列出当前数据库中有哪些表已经采用sqlcachedependency功能;

3.0使用SqlCacheDependency 

在代码中使用缓存,并为其设置SqlCacheDependency依赖:

 

/// <summary>/// 获取当前应用程序指定CacheKey的Cache对象值/// </summary>/// <param name="CacheKey">索引键值</param>/// <returns>返回缓存对象</returns>public static object GetCache(string CacheKey){ ???System.Web.Caching.Cache objCache = HttpRuntime.Cache; ???return objCache[CacheKey];}/// <summary>/// 设置以缓存依赖的方式缓存数据/// </summary>/// <param name="CacheKey">索引键值</param>/// <param name="objObject">缓存对象</param>/// <param name="cacheDepen">依赖对象</param>public static void SetCache(string CacheKey, object objObject, System.Web.Caching.CacheDependency dep){ ???System.Web.Caching.Cache objCache = HttpRuntime.Cache; ???objCache.Insert( ???????CacheKey, ???????objObject, ???????dep, ???????System.Web.Caching.Cache.NoAbsoluteExpiration,//从不过期 ???????System.Web.Caching.Cache.NoSlidingExpiration,//禁用可调过期 ???????System.Web.Caching.CacheItemPriority.Default, ???????null);}protected void Page_Load(object sender, EventArgs e){ ???string CacheKey = "cachetest"; ???object objModel = GetCache(CacheKey);//从缓存中获取 ???if (objModel == null)//缓存里没有 ???{ ???????objModel = GetData();//把当前时间进行缓存 ???????if (objModel != null) ???????{ ???????????//依赖数据库codematic中的P_Product表变化 来更新缓存 ???????????System.Web.Caching.SqlCacheDependency dep = new System.Web.Caching.SqlCacheDependency("CodeMatic", "P_Product"); ???????????SetCache(CacheKey, objModel, dep);//写入缓存 ???????} ???} ????GridView1.DataSource = (DataSet)objModel; ???GridView1.DataBind();}

从以上代码可以看出,和文件依赖基本相同,只是在存放缓存SetCache时存入的依赖对象不同。这里用的是SqlCacheDependency。

其中,创建SqlCacheDependency的构造方法:

public SqlCacheDependency (string databaseEntryName,string tableName)//databaseEntryName:是在Web.config文件的caching节的sqlCacheDependency的databases元素中定义的数据库的名称。 //tableName:与SqlCacheDependency关联的数据库表的名称。//这样,只有当P_Product表的内容发生变化时,查询操作才会重新查询数据更新缓存的内容,可以大大减少数据库的重复查询和提高系统的性能和运行效率。

七、缓存管理类

首先,缓存管理类外部代码定义了各种过期时间的常量,主要用于方便设定缓存的过期时间

/// <summary> ???/// 全站缓存类 ???/// </summary> ???public sealed class SiteCache ???{ ???????// 一天 ???????public const int DayFactor = 17280; ???????// 一小时 ???????public const int HourFactor = 720; ???????// 一分钟 ???????public const int MinuteFactor = 12; ????????// 一秒 ???????public const double SecondFactor = 0.2; ???????private static int factor = 5; ???????/// <summary> ???????/// 时间因子 ???????/// </summary> ???????public static int Factor ???????{ ???????????get { return factor; } ???????????set { factor = value; } ???????} public static Cache CurrentCache { ???????????get { ???????????????return HttpRuntime.Cache; ???????????} ???????} ???????}
//Clear方法用于移除所有存储在内存当中的缓存,代码中cacheEnum变量通过GetEnumerator方法获得所有缓存列表,再根据缓存列表来移除缓存。 ???????public static void Clear() ???????{ ???????????//获取缓存中的键设置及其值的字典枚举数 ???????????IDictionaryEnumerator cacheEnum = siteCache.GetEnumerator(); ???????????ArrayList al = new ArrayList(); ???????????//循环添加到数组列表 ???????????while (cacheEnum.MoveNext()) ???????????{ ???????????????al.Add(cacheEnum.Key); ???????????} ???????????//循环从缓存中移除 ???????????foreach (string key in al) ???????????{ ???????????????siteCache.Remove(key); ???????????} ???????}
//RemoveByPattern方法是通过正则移除对应的缓存。 public static void RemoveByPattern(string pattern) ???????{ ???????????IDictionaryEnumerator cacheEnum = siteCache.GetEnumerator(); ???????????Regex regex = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled); ???????????ArrayList al = new ArrayList(); ???????????//循环从缓存中取出键进行正则条件匹配 ???????????while (cacheEnum.MoveNext()) ???????????{ ???????????????//匹配正确则添加到数组列表 ???????????????if (regex.IsMatch(cacheEnum.Key.ToString())) ???????????????{ ???????????????????al.Add(cacheEnum.Key); ???????????????} ???????????} ???????????//移除匹配正则的缓存 ???????????foreach (string key in al) ???????????{ ???????????????siteCache.Remove(key); ???????????} ???????}
//Insert方法是通过Cache的插入方法而实现的,主要能够把缓存键、缓存对象、缓存依赖、缓存过期时间、缓存级别这些缓存项插入到内存中。 ???/// <summary> ???????/// 插入缓存项 ???????/// </summary> ???????public static void Insert(string key, object value, System.Web.Caching.CacheDependency dep, int seconds, CacheItemPriority priority) ???????{ ???????????if (value != null) ???????????{ ???????????????siteCache.Insert(key, value, dep, DateTime.Now.AddSeconds(Factor * seconds), TimeSpan.Zero, priority, null); ???????????} ???????}
//Get方法通过指定的键从Cache中获取缓存 ???????public static object Get(string key) ???????{ ???????????return siteCache[key]; ???????} ???}

 八、缓存的应用规则

缓存分配的有效期不要太短。
缓存那些经常被访问,同时变化频率不大的数据。
缓存整个应用程序都要使用的设置或对象,并且这些设置和对象在生存期内不会频繁变化。
不要缓存太多项,缓存每个项均有开销。
不要缓存很少使用的项。
不要缓存容易重新计算或随时都可能会修改的对象,如购物车。
不要缓存敏感信息,否则其他人很容易取得这些信息。

比如:可以缓存网站信息配置

GetConfig是一个泛型方法,网站信息配置里的所有功能属性都是通过它来获得对象。方法后面跟着一个where子句,用于指定对类型的约束。其中class限制了类型参数必须是引用类型, new()限制了该类型参数必须具有无参数的公共构造函数。

方法内首先获取了T变量的类型。然后根据类型名拼装成configCacheKey缓存键,通过SiteCache类的Get方法获取缓存的值并存储到configObject变量中。接着判断该缓存是否不存在值,如果不存在,使用GetConfigPath方法获得了T变量的物理文件地址。

public static T GetConfig<T>() where T : class, new(){ ????Type configClassType = typeof(T); ????string configCacheKey = "CK_SiteConfigCode_" + configClassType.Name; ????object configObject = SiteCache.Get(configCacheKey); ????if (configObject == null) ????{ ?????????string configFilePath = GetConfigPath<T>();//下面检查T变量的物理文件地址是否存在,如果存在即读取T变量的配置信息,并将信息插入到缓存中。其中Insert方法使用了缓存依赖CacheDependency实例监视文件或目录路径,当该资源更改时,缓存的对象将过时,从缓存中移除。 ?????????if (File.Exists(configFilePath)) ?????????{ ?????????????using (XmlTextReader xmlTextReader = new XmlTextReader(configFilePath)) ?????????????{ ??????????????????XmlSerializer xmlSerializer = new XmlSerializer(configClassType); ??????????????????configObject = xmlSerializer.Deserialize(xmlTextReader); ?????????????} ?????????????SiteCache.Insert(configCacheKey, configObject, new CacheDependency(configFilePath)); ??????????} ????}//最后,把缓存对象转换为T泛型变量。判断是否为空,如果是则创建新的T实例返回,否则将原有值返回。 ????T config = configObject as T; ????if (config == null) ????{ ????????return new T(); ????} ????else ????{ ????????return config; ????}} 

Asp.Net 基础知识回顾_Cache

原文地址:https://www.cnblogs.com/entclark/p/8654918.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved