您的位置:首页 > 编程语言 > ASP

ASP.NET 缓存(Cache)介绍

2012-02-15 15:31 381 查看

ASP.NET缓存(Cache)介绍

ASP.NET缓存概述

通常,应用程序可以将那些频繁访问的数据,以及那些需要大量处理时间来创建的数据存储在内存中,从而提高性能。例如,如果应用程序使用复杂的逻辑来处理大量数据,然后再将数据作为用户频繁访问的报表返回,避免在用户每次请求数据时重新创建报表可以提高效率。同样,如果应用程序包含一个处理复杂数据但不需要经常更新的页,则在每次请求时服务器都重新创建该页会使工作效率低下。

在这些情况下,为了帮助您提高应用程序的性能,ASP.NET使用两种基本的缓存机制来提供缓存功能。第一种机制是应用程序缓存,它允许您缓存所生成的数据,如
DataSet或自定义报表业务对象。第二种机制是页输出缓存,它保存页处理输出,并在用户再次请求该页时,重用所保存的输出,而不是再次处理该页。

应用程序缓存

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

使用应用程序缓存的模式是,确定在访问某一项时该项是否存在于缓存中,如果存在,则使用。如果该项不存在,则可以重新创建该项,然后将其放回缓存中。这一模式可确保缓存中始终有最新的数据。

有关更多信息,请参见如何:检索缓存项的值。

页输出缓存

页输出缓存在内存中存储处理后的ASP.NET页的内容。这一机制允许ASP.NET向客户端发送页响应,而不必再次经过页处理生命周期。页输出缓存对于那些不经常更改,但需要大量处理才能创建的页特别有用。例如,如果创建大通信量的网页来显示不需要频繁更新的数据,页输出缓存则可以极大地提高该页的性能。可以分别为每个页配置页缓存,也可以在Web.config文件中创建缓存配置文件。利用缓存配置文件,只定义一次缓存设置就可以在多个页中使用这些设置。

页输出缓存提供了两种页缓存模型:整页缓存和部分页缓存。整页缓存允许将页的全部内容保存在内存中,并用于完成客户端请求。部分页缓存允许缓存页的部分内容,其他部分则为动态内容。有关更多信息,请参见缓存ASP.NET页。

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

缓存后替换与控件缓存正好相反。这种方式缓存整个页,但页中的各段都是动态的。例如,如果要创建一个在规定时间段内为静态的页,则可以将整个页设置为进行缓存。如果向页添加一个显示用户名的

Label控件,则对于每次页刷新和每个用户而言,Label的内容都将保持不变,始终显示缓存该页之前请求该页的用户的姓名。但是,使用缓存后替换机制,可以将页配置为进行缓存,但将页的个别部分标记为不可缓存。在此情况下,可以向不可缓存部分添加
Label控件,这样将为每个用户和每次页请求动态创建这些控件。有关更多信息,请参见缓存ASP.NET页的某些部分。

根据请求参数缓存页

除缓存页的单一版本外,ASP.NET页输出缓存还提供了一些功能,可以创建根据请求参数的不同而不同的页的多个版本。有关更多信息,请参见缓存页的多个版本。

自动移除数据

出于以下原因之一,ASP.NET可以从缓存中移除数据:

由于服务器上的内存不足,开始一个称为“清理”的过程。

由于缓存中的项已过期。

由于项的依赖项发生了更改。

为了帮助管理缓存项,在将项从缓存中移除时,ASP.NET会通知应用程序。

清理

清理是在内存不足时从缓存中删除项的过程。如果某些项在一段时间内未被访问,或是在添加到缓存中时被标记为低优先级,则这些项会被移除。ASP.NET使用
CacheItemPriority对象来确定要首先清理的项。有关更多信息,请参见如何:将项添加到缓存中。

过期

除了清理外,在缓存项过期时,ASP.NET会自动从缓存中移除这些项。向缓存添加项时,可以按下表中的描述设置其过期时间。

过期类型说明
可调过期

指定某项自上次被访问后多长时间过期。例如,可以将某项设置为自上次在缓存中被访问后20分钟过期。

绝对过期

指定某项在设定的时间过期,而不考虑访问频率。例如,可以将某项设置为在6:00PM过期,或四小时后过期。

依赖项

可以将缓存中某一项的生存期配置为依赖于其他应用程序元素,如某个文件或数据库。当缓存项依赖的元素更改时,ASP.NET将从缓存中移除该项。例如,如果您的网站显示一份报告,该报告是应用程序通过XML文件创建的,您可以将该报告放置在缓存中,并将其配置为依赖于该XML文件。当XML文件更改时,ASP.NET会从缓存中移除该报告。当代码请求该报告时,代码会先确定该报告是否在缓存中,如果不在,代码会重新创建该报告。因此,始终都有最新版本的报告可用。

ASP.NET缓存支持下表中描述的依赖项。

依赖项说明
键依赖项

应用程序缓存中的项存储在键/值对中。键依赖项允许项依赖于应用程序缓存中另一项的键。如果移除了原始项,则具有键依赖关系的项也会被移除。例如,可以添加一个名为
ReportsValid的缓存项,然后缓存若干个依赖于ReportsValid键的报告。当ReportsValid项被移除时,所有依赖于它的缓存报告同样也会从缓存中移除。

文件依赖项

缓存中的项依赖于外部文件。如果该文件被修改或删除,则缓存项也会被移除。

SQL依赖项

缓存中的项依赖于MicrosoftSQLServer2005、SQLServer2000或SQLServer7.0数据库中表的更改。对于SQLServer2005,缓存中的项可依赖于表中的某一行。有关更多信息,请参见使用SqlCacheDependency类在ASP.NET中缓存。

聚合依赖项

通过使用
AggregateCacheDependency类缓存中的项依赖于多个元素。如果任何依赖项发生更改,该项都会从缓存中移除。

自定义依赖项

可以用您自己的代码创建的依赖关系来配置缓存中的项。例如,可以创建一个自定义Web服务缓存依赖项,当调用Web服务得到一个特定值时,该依赖项就会从缓存中移除数据。

应用程序缓存项移除通知

当项从应用程序缓存中移除时,您可以收到通知。例如,如果有一个需要大量处理时间才能创建的项,当从缓存中移除该项时,您会收到通知以便可以立即替换该项。这样,下次请求该项时,用户便不必等待处理该项。有关更多信息,请参见如何:从缓存中移除项时通知应用程序。

ASP.NET缓存中的新增功能

ASP.NET2.0版保留了ASP.NET1.1版的所有缓存功能,同时添加了新功能并增强了现有功能。新功能包括缓存配置文件、自定义缓存依赖项、SQL缓存依赖项以及在缓存页中创建动态内容(缓存后替换)。增强功能包括功能更强大的部分页(控件)缓存模型、增强的缓存配置以及输出缓存指令的改进。

新缓存功能

缓存配置文件

缓存配置文件使您能够在应用程序的Web.config文件中创建缓存设置,然后在单个页上引用这些设置。这使您能够将缓存设置同时应用于多页。例如,可以定义一个名为DailyUpdate的缓存配置文件,它将页的缓存持续时间设置为一天。然后可以配置各个页使用DailyUpdate缓存配置文件,并且这些页的缓存持续时间为一天。如果将DailyUpdate缓存配置文件更改为不使用缓存,将停止缓存这些页。有关更多信息,请参见
ASP.NET中的缓存配置。

自定义缓存依赖项

在ASP.NET2.0中,您可以根据应用程序特定情况创建自己的自定义缓存依赖项。若要创建自定义缓存依赖项,请创建从
CacheDependency继承的类并在自定义类中实现您自己的依赖项方法。例如,您可以创建在Web服务中轮询数据的依赖项;当数据发生变化时,您可以使缓存数据无效。若要了解通过指定依赖项向缓存添加项目的信息,请参见如何:将项添加到缓存中。

SqlCacheDependency

ASP.NET2.0引入了
SqlCacheDependency类,它使您能够在缓存中配置一个项,以便在MicrosoftSQLServer数据库中的表或行上拥有依赖项。当表中或特定行中发生更改时,具有依赖项的缓存项便会失效并从缓存中移除。ASP.NET2.0使您能够在SQLServer7.0、SQLServer2000和SQLServer2005中设置表的依赖项。使用SQLServer2005时,您还可以设置特定记录的依赖项。有关更多信息,请参见使用
SqlCacheDependency类在ASP.NET中缓存。

缓存后替换

ASP.NET2.0现在支持缓存后替换,使您能够将页中的某一部分配置为不可缓存。因此,尽管缓存了该页,但在再次请求该页时,将重新处理它的部分内容。例如,您可以使用大多数静态内容(但不能使用在

Label控件中显示用户名的内容)创建缓存页。如果不使用缓存后替换,用户名在所有请求中保持不变。如果使用缓存后替换,您可以将页标记为可缓存,然后将
Label
控件放置在标记为不可缓存的另一个控件中。此后每次请求该页时,都会刷新用户名。有关更多信息,请参见缓存ASP.NET页的某些部分。

缓存增强

控件缓存

在ASP.NET1.1中,通过设置
@Control指令中的参数以声明方式配置用户控件缓存。在ASP.NET2.0中,可以在运行时使用
CachePolicy对象配置用户控件缓存设置。CachePolicy对象使您能够按照以编程方式处理页输出缓存的相同方式处理用户控件缓存。有关更多信息,请参见缓存ASP.NET页的某些部分。

缓存配置增强

除了缓存配置文件外,ASP.NET2.0中还引入了新的缓存配置设置,可以在应用程序的Web.config文件中指定这些设置。这些设置增加了您对缓存的控制,如内存使用量和缓存清理行为。有关更多信息,请参见
ASP.NET中的缓存配置。

输出缓存指令改进

ASP.NET2.0包括新的
@OutputCache指令选项以及对现有选项的增强。新功能和增强功能使您能够对输出缓存功能进行声明控制,而以前只能使用
HttpCachePolicy类以编程方式实现此类控制。例如,现在可以用声明方式设置页
@OutputCache指令中的
Duration属性和
NoStore属性。有关更多信息,请参见设置页的可缓存性。

缓存应用程序数据

ASP.NET为您提供了一个强大的、便于使用的缓存机制,用于将需要大量服务器资源来创建的对象存储在内存中。缓存这些类型的资源会大大改进应用程序的性能。

缓存是由
Cache类实现的;缓存实例是每个应用程序专用的。缓存生存期依赖于应用程序的生存期;重新启动应用程序后,将重新创建Cache对象。

设计Cache类是为了便于使用。您可以将项放置在Cache中,并在以后使用简单的键/值对来检索这些项。有关如何执行此操作的示例,请参见如何:将项添加到缓存中和如何:检索缓存项的值。

Cache类提供了强大的功能,允许您自定义如何缓存项以及将它们缓存多长时间。例如,当缺乏系统内存时,缓存会自动移除很少使用的或优先级较低的项以释放内存。该技术也称为清理,这是缓存确保过期数据不使用宝贵的服务器资源的方式之一。

当执行清理时,您可以指示Cache给予某些项比其他项更高的优先级。若要指示项的重要性,可以在使用
Add或
Insert方法添加项时指定一个
CacheItemPriority枚举值。

当使用AddInsert方法将项添加到缓存时,您还可以建立项的过期策略。您可以通过使用

DateTime值指定项的确切过期时间(绝对过期时间),来定义项的生存期。也可以使用
TimeSpan值指定一个弹性过期时间,弹性过期时间允许您根据项的上次访问时间来指定该项过期之前的运行时间。一旦项过期,便将它从缓存中移除。试图检索它的值的行为将返回
null(在VisualBasic中为Nothing),除非该项被重新添加到缓存中。

对于存储在缓存中的易失项(例如那些定期进行数据刷新的项或那些只在一段时间内有效的项),通常设置一种过期策略:只要这些项的数据保持为最新的,就将它们保留在缓存中。例如,如果您正在编写一个应用程序,该应用程序通过另一个网站获取数据来跟踪体育比赛的比分,那么只要源网站上比赛的比分不更改,就可以缓存这些比分。在此情况下,您可以根据其他网站更新比分的频率来设置过期策略。您可以编写代码来确定缓存中是否是最新的比分。如果该比分不是最新的,则代码可以从源网站读取比分并缓存新值。

最后,ASP.NET允许您根据外部文件、目录(文件依赖项)或另一个缓存项(键依赖项)来定义缓存项的有效性。如果具有关联依赖项的项发生更改,缓存项便会失效并从缓存中移除。您可以使用该技术在项的数据源更改时从缓存中移除这些项。例如,如果您编写一个处理XML文件中的财务数据的应用程序,则可以从该文件将数据插入缓存中并在此XML文件上保留一个依赖项。当该文件更新时,从缓存中移除该项,您的应用程序重新读取XML文件,然后将刷新后的数据放入缓存中。


注意
Cache对象没有关于它所包含项的内容的信息。它只保留对这些对象的引用。它还提供跟踪它们的依赖项和设置到期策略的方法。

ASP.NET中的缓存配置

ASP.NET提供了许多可用于配置页面输出缓存和缓存API的选项。可以在处理了页面响应后使用页面输出缓存来缓存此页面响应。也可以通过编程的方式使用缓存API来缓存应用程序数据。有关更多信息,请参见
ASP.NET缓存概述。

页面输出缓存配置

您可以在以下这些位置配置页面输出缓存:

配置文件可以在应用程序配置层次结构的任何配置文件中配置页面输出缓存设置,包括Machine.config文件(用于设置计算机上所有的Web应用程序)和特定于应用程序的Web.config文件(用于设置单个应用程序)。

单个页面可以在单个页面中以声明方式或编程方式设置缓存选项。还可将在配置文件中创建的缓存配置文件应用于单个页面。

用户控件可以在单个用户控件中以声明方式或编程方式设置缓存。对于在其他情况下不缓存的页面内容来说,这是一种简便的缓存方法。

Web.config缓存配置设置

在Web.config文件中,有两个顶级配置节可用于页输出缓存:OutputCacheSection和

OutputCacheSettingsSection。

OutputCacheSection节用于配置应用程序范围的设置,例如是启用还是禁用页输出缓存。例如,您可以通过向Web.config文件中的
OutputCacheSection添加enableOutputCache="false"来对整个应用程序禁用页输出缓存。由于配置文件中的设置要优先于单个页面中的缓存设置,因此,示例设置将导致不使用输出缓存。

OutputCacheSettingsSection用于配置可由单个页使用的配置文件和依赖项。例如,下面的代码创建了一个名为
CacheProfile1的
OutputCacheProfile,它将缓存实现页60秒:

<outputCacheSettings>
<outputCacheProfiles>
<addname="CacheProfile1"duration="60"/>
</outputCacheProfiles>
</outputCacheSettings>


Machine.config缓存配置设置

Machine.config文件的配置节与Web.config文件的配置节基本相同,而只有一点区别:即可以锁定Machine.config文件中的配置设置,使任何级别的单个应用程序都无法重写这些配置设置。在宿主不希望单个应用程序修改缓存配置时,可能有必要在共享宿主方案中使用此功能。有关更多信息,请参见如何:锁定ASP.NET配置设置。

页面缓存配置设置

通过应用在配置文件中定义的缓存配置文件,可以配置单个页中的缓存。也可以在
@OutputCache指令中配置单个缓存属性(property),或者通过设置页的类定义中的属性(attribute)进行配置。有关更多信息,请参见
@OutputCache和设置页的可缓存性。

用户控件缓存配置设置

通过设置用户控件文件中的
@OutputCache指令,或设置控件类定义中的
PartialCachingAttribute属性,可以对用户控件缓存进行配置。有关更多信息,请参见缓存ASP.NET页的某些部分。

缓存API配置设置

可以在Web.config文件中配置应用程序的缓存API。对于页面输出缓存,应用程序宿主可以在Machine.config文件中设置配置属性,并锁定所有应用程序的缓存配置设置。应用程序缓存API在

CacheSection中进行配置。例如,您可以使用下面的配置元素来禁用项过期:

<cachedisableExpiration="true"/>

还可以通过为属性(如配置文件的CacheSection中的
DisableExpiration和
DisableMemoryCollection属性)赋值的方式来指定其他应用程序缓存API配置设置。

如何:将项添加到缓存中

可以使用
Cache对象访问应用程序缓存中的项。可以使用Cache对象的
Insert方法向应用程序缓存添加项。该方法向缓存添加项,并且通过几次重载,您可以用不同选项添加项,以设置依赖项、过期和移除通知。如果使用
Insert
方法向缓存添加项,并且已经存在与现有项同名的项,则缓存中的现有项将被替换。

还可以使用
Add方法向缓存添加项。使用此方法,您可以设置与Insert方法相同的所有选项;然而,Add方法将返回您添加到缓存中的对象。另外,如果使用
Add方法,并且缓存中已经存在与现有项同名的项,则该方法不会替换该项,并且不会引发异常。

本主题中的过程阐释了向应用程序缓存添加项的如下方式:

通过键和值直接设置项,向缓存添加项。

使用Insert方法向缓存添加项。

向缓存添加项并添加依赖项,以便当该依赖项更改时,将该项从缓存中移除。可以基于其他缓存项、文件和多个对象设置依赖项。

将设有过期策略的项添加到缓存中。除了能设置项的依赖项以外,还可以设置项在一段时间以后(弹性过期)或在指定时间(绝对过期)过期。您可以定义绝对过期时间或弹性过期时间,但不能同时定义两者。

向缓存添加项,并定义缓存的项的相对优先级。相对优先级帮助.NETFramework确定要移除的缓存项;较低优先级的项比较高优先级的项先从缓存中移除。

通过调用Add方法添加项。

除了这里显示的依赖项,可以在SQLServer表上或基于自定义依赖项创建依赖项。有关更多信息,请参见
ASP.NET缓存概述和使用SqlCacheDependency类在ASP.NET中缓存。

当从缓存中移除项时,还可以使用
CacheItemRemovedCallback委托让应用程序缓存通知应用程序。有关完整示例,请参见如何:从缓存中移除项时通知应用程序。

通过键和值直接设置项向缓存添加项

通过指定项的键和值,像将项添加到字典中一样将其添加到缓存中。

下面的代码示例将名为CacheItem1的项添加到Cache对象中:

C#


复制代码

Cache["CacheItem1"]="CachedItem1";


VisualBasic


复制代码

Cache("CacheItem1")="CachedItem1"


通过使用Insert方法将项添加到缓存中

调用Insert方法,传递要添加的项的键和值。

下面的代码示例添加名为CacheItem2的字符串:

C#


复制代码

Cache.Insert("CacheItem2","CachedItem2");


VisualBasic


复制代码

Cache.Insert("CacheItem2","CachedItem2")


通过指定依赖项向缓存添加项

调用Insert方法,将
CacheDependency对象的一个实例传递给该方法

下面的代码示例添加名为CacheItem3的项,该项依赖于缓存中名为CacheItem2的另一个项:

C#


复制代码

string[]dependencies={"CacheItem2"};
Cache.Insert("CacheItem3","CachedItem3",
newSystem.Web.Caching.CacheDependency(null,dependencies));


VisualBasic


复制代码

DimdependenciesAsString()={"CacheItem2"}
Cache.Insert("CacheItem3","CachedItem3",_
NewSystem.Web.Caching.CacheDependency(_
Nothing,dependencies))

下面的代码示例演示将名为CacheItem4的项添加到缓存中,并且在名为XMLFile.xml的文件上设置文件依赖项:

C#


复制代码

Cache.Insert("CacheItem4","CachedItem4",
newSystem.Web.Caching.CacheDependency(
Server.MapPath("XMLFile.xml")));


VisualBasic


复制代码

Cache.Insert("CacheItem4","CachedItem4",_
NewSystem.Web.Caching.CacheDependency(_
Server.MapPath("XMLFile.xml")))

下面的代码示例演示如何创建多个依赖项。它向缓存中名为CacheItem1的另一个项添加键依赖项,向名为XMLFile.xml的文件添加文件依赖项。

C#


复制代码

System.Web.Caching.CacheDependencydep1=
newSystem.Web.Caching.CacheDependency(Server.MapPath("XMLFile.xml"));
string[]keyDependencies2={"CacheItem1"};
System.Web.Caching.CacheDependencydep2=
newSystem.Web.Caching.CacheDependency(null,keyDependencies2);
System.Web.Caching.AggregateCacheDependencyaggDep=
newSystem.Web.Caching.AggregateCacheDependency();
aggDep.Add(dep1);
aggDep.Add(dep2);
Cache.Insert("CacheItem5","CachedItem5",aggDep);


VisualBasic


复制代码

Dimdep1AsCacheDependency=_
NewCacheDependency(Server.MapPath("XMLFile.xml"))
DimkeyDependencies2AsString()={"CacheItem1"}
Dimdep2AsCacheDependency=_
NewSystem.Web.Caching.CacheDependency(Nothing,_
keyDependencies2)
DimaggDepAsAggregateCacheDependency=_
NewSystem.Web.Caching.AggregateCacheDependency()
aggDep.Add(dep1)
aggDep.Add(dep2)
Cache.Insert("CacheItem5","CachedItem5",aggDep)


将设有过期策略的项添加到缓存中

调用Insert方法,将绝对过期时间或弹性过期时间传递给该方法。

下面的代码示例将有一分钟绝对过期时间的项添加到缓存中:

C#


复制代码

Cache.Insert("CacheItem6","CachedItem6",
null,DateTime.Now.AddMinutes(1d),
System.Web.Caching.Cache.NoSlidingExpiration);


VisualBasic


复制代码

Cache.Insert("CacheItem6","CachedItem6",_
Nothing,DateTime.Now.AddMinutes(1.0),_
TimeSpan.Zero)

下面的代码示例将有10分钟弹性过期时间的项添加到缓存中:

C#


复制代码

Cache.Insert("CacheItem7","CachedItem7",
null,System.Web.Caching.Cache.NoAbsoluteExpiration,
newTimeSpan(0,10,0));


VisualBasic


复制代码

Cache.Insert("CacheItem7","CachedItem7",_
Nothing,System.Web.Caching.Cache.NoAbsoluteExpiration,_
NewTimeSpan(0,10,0))


将设有优先级设置的项添加到缓存中

调用Insert方法,从
CacheItemPriority枚举中指定一个值。

下面的代码示例将优先级值为
High的项添加到缓存中:

C#


复制代码

Cache.Insert("CacheItem8","CachedItem8",
null,System.Web.Caching.Cache.NoAbsoluteExpiration,
System.Web.Caching.Cache.NoSlidingExpiration,
System.Web.Caching.CacheItemPriority.High,null);


VisualBasic


复制代码

Cache.Insert("CacheItem8","CachedItem8",_
Nothing,System.Web.Caching.Cache.NoAbsoluteExpiration,_
System.Web.Caching.Cache.NoSlidingExpiration,_
System.Web.Caching.CacheItemPriority.High,_
Nothing)


使用Add方法向缓存添加项

调用Add方法,它返回一个表示项的对象。

下面的代码示例向缓存添加名为CacheItem9的项,同时将变量CachedItem9的值设置为已添加的项。

C#


复制代码

stringCachedItem9=(string)Cache.Add("CacheItem9",
"CachedItem9",null,
System.Web.Caching.Cache.NoAbsoluteExpiration,
System.Web.Caching.Cache.NoSlidingExpiration,
System.Web.Caching.CacheItemPriority.Default,
null);


VisualBasic


复制代码

DimCachedItem9AsString=CStr(Cache.Add("CacheItem9",_
"CachedItem9",Nothing,_
System.Web.Caching.Cache.NoAbsoluteExpiration,_
System.Web.Caching.Cache.NoSlidingExpiration,_
System.Web.Caching.CacheItemPriority.Default,_
Nothing))


如何:检索缓存项的值要从缓存中检索数据,应指定存储缓存项的键。不过,由于缓存中所存储的信息为易失信息,即该信息可能由ASP.NET移除,因此建议的开发模式是首先确定该项是否在缓存中。如果不在,则应将它重新添加到缓存中,然后检索该项。

检索缓存项的值

通过在Cache对象中进行检查来确定该项是否不为null(在VisualBasic中为Nothing)。如果该项存在,则将它分配给变量。否则,重新创建该项,将它添加到缓存中,然后访问它。 下面的代码示例演示如何从缓存中检索名为CacheItem的项。代码将该项的内容分配给名为cachedString的变量。如果该项不在缓存中,则代码会将它添加到缓存中,然后将它分配给cachedString。 C# 复制代码stringcachedString; cachedString=(string)Cache["CacheItem"]; if(cachedString==null) { cachedString="Hello,World."; Cache.Insert("CacheItem",cachedString); }


VisualBasic


复制代码

DimcachedStringAsString
cachedString=CStr(Cache("CacheItem"))
IfcachedStringIsNothingThen
cachedString="Hello,World."
Cache.Insert("CacheItem",cachedString)
EndIf


如何:从缓存中移除项时通知应用程序在大多数缓存方案中,当从缓存中移除项后,直到再次需要此项时,才需要将其放回缓存中。典型的开发模式是在使用项之前始终检查该项是否已在缓存中。如果项位于缓存中,则可以使用。如果不在缓存中,则应再次检索该项,然后将其添加回缓存。
但是,在某些情况下,如果从缓存中移除项时通知应用程序,可能非常有用。例如,您可能具有一个缓存的报告,创建该报告需花费大量的时间进行处理。当该报告从缓存中移除时,您希望重新生成该报告,并立即将其置于缓存中,以便下次请求该报告时,用户不必等待对此报告进行处理。
为了在从缓存中移除项时能够发出通知,ASP.NET提供了CacheItemRemovedCallback委托。该委托定义编写事件处理程序时使用的签名,当对从缓存中移除项进行响应时会调用此事件处理程序。ASP.NET还提供CacheItemRemovedReason枚举,用于指定移除缓存项的原因。
通常,通过在管理尝试检索的特定缓存数据的业务对象中创建处理程序,来实现回调。例如,您可能有一个ReportManager对象,该对象具有两种方法,即GetReport和CacheReport。GetReport报告方法检查缓存以查看报告是否已缓存;如果没有,该方法将重新生成报告并将其缓存。CacheReport方法具有与CacheItemRemovedCallback委托相同的函数签名;从缓存中移除报告时,ASP.NET会调用CacheReport方法,然后将报告重新添加到缓存中。

当从缓存中移除项时通知应用程序

创建一个类,负责从缓存中检索项并处理回调方法,以将项添加回缓存中。 在该类中,创建用于将项添加到缓存中的方法。 在该类中,创建用于从缓存中获取项的方法。 创建用于处理缓存项移除回调的方法。该方法必须具备与CacheItemRemovedCallback委托相同的函数签名。从缓存中删除项时,会在该方法中执行要运行的逻辑,如重新生成项并将其添加回缓存中。

测试缓存项回调

创建一个ASP.NET网页,该网页将调用类中用于将项添加到缓存中的方法。 下面的代码示例演示如何调用ReportManager类的GetReport方法(在此过程后面的示例中定义)。然后将在使用页面的Page_Load方法期间显示Label控件Label1中的报告。 C# 复制代码protectedvoidPage_Load(objectsender,EventArgse) { this.Label1.Text=ReportManager.GetReport(); }


VisualBasic


复制代码

ProtectedSubPage_Load(ByValsenderAsObject,_
ByValeAsSystem.EventArgs)HandlesMe.Load
Me.Label1.Text=ReportManager.GetReport()
EndSub


在浏览器中请求ASP.NET页并查看报告。

报告是在首次请求页时创建的,在缓存中的报告被移除之前,后续请求都将访问缓存中的报告。

示例

下面的代码示例演示一个名为ReportManager的、用于在从缓存中删除项时处理通知的完整类。该类管理字符串形式的报告,此报告表示一个长期运行的进程。

尽管该示例使用声明为static(在VisualBasic中为Shared)的类,但并不是必须使用静态类。不过,删除缓存项时,用于处理回调的方法必须存在。例如,不应在ASP.NET页中实现回调处理程序,因为在从缓存中删除项之前该页可能已被释放,因此用于处理回调的方法将不可用。为了确保从缓存中删除项时处理回调的方法仍然存在,请使用该方法的静态类。但是,静态类的缺点是需要保证所有静态方法都是线程安全的。


警告
请不要在页面中将CacheItemRemovedCallback设置为一个方法。除了在释放页面后回调无法使用页面方法以外,将回调指向页面方法还会阻碍垃圾回收将页面使用的内存回收。由于回调包含对页面的引用,而垃圾回收器不会从内存中移除包含任何引用的项,因此会出现这种情况。在加载应用程序期间,这可能会导致内存很快被用光。

该示例类包括以下功能:

私有成员,用于跟踪报告是否已从缓存中移除。

名为CacheReport的方法,用于将项以MyReport的名称添加到缓存中,并将该项设置为在添加到缓存中后一分钟过期。该方法还会将
ReportRemovedCallback方法传递给onRemoveCallback参数,从而注册
ReportRemoveCallback方法,以便在从缓存中删除项时进行调用。

名为GetReport的方法,用于从缓存中获取项。该方法确定名为MyReport的项是否存在于缓存中。如果该项不存在,则该方法将调用
CacheReport,,将该项添加到缓存中。

名为ReportRemovedCallback的方法,用于处理缓存项移除回调。ReportRemovedCallback具有与
CacheItemRemovedCallback委托相同的函数签名。该方法将变量_reportRemovedFromCache设置为
true,然后通过CacheReport方法将项添加回缓存中。

C#


复制代码

usingSystem;
usingSystem.Web;
usingSystem.Web.Caching;
publicstaticclassReportManager
{
privatestaticbool_reportRemovedFromCache=false;
staticReportManager()
{}

publicstaticStringGetReport()
{
lock(typeof(ReportManager))
{
if(HttpContext.Current.Cache["MyReport"]!=null)
return(string)HttpRuntime.Cache["MyReport"];
else
{
CacheReport();
return(string)HttpRuntime.Cache["MyReport"];
}
}
}

publicstaticvoidCacheReport()
{
lock(typeof(ReportManager))
{
HttpContext.Current.Cache.Add("MyReport",
CreateReport(),null,DateTime.MaxValue,
newTimeSpan(0,1,0),
System.Web.Caching.CacheItemPriority.Default,
ReportRemovedCallback);
}
}

privatestaticstringCreateReport()
{
System.Text.StringBuildermyReport=
newSystem.Text.StringBuilder();
myReport.Append("SalesReport<br/>");
myReport.Append("2005Q2Figures<br/>");
myReport.Append("SalesNERegion-$2million<br/>");
myReport.Append("SalesNWRegion-$4.5million<br/>");
myReport.Append("ReportGenerated:"+DateTime.Now.ToString()
+"<br/>");
myReport.Append("ReportRemovedFromCache:"+
_reportRemovedFromCache.ToString());
returnmyReport.ToString();
}

publicstaticvoidReportRemovedCallback(Stringkey,objectvalue,
CacheItemRemovedReasonremovedReason)
{
_reportRemovedFromCache=true;
CacheReport();
}
}


VisualBasic


复制代码

ImportsSystem
ImportsSystem.Web
ImportsSystem.Web.Caching
PublicClassReportManager
PrivateShared_reportRemovedFromCacheAsBoolean=False
SharedSubNew()
EndSub

PrivateSubNew()
EndSub

PublicSharedFunctionGetReport()AsString
SyncLock(GetType(ReportManager))
IfHttpContext.Current.Cache("MyReport")IsNotNothingThen
ReturnCStr(HttpRuntime.Cache("MyReport"))
Else
CacheReport()
ReturnCStr(HttpRuntime.Cache("MyReport"))
EndIf
EndSyncLock
EndFunction

PublicSharedSubCacheReport()
SyncLock(GetType(ReportManager))
HttpContext.Current.Cache.Add("MyReport",CreateReport(),_
Nothing,DateTime.MaxValue,NewTimeSpan(0,1,0),_
System.Web.Caching.CacheItemPriority.Default,_
AddressOfReportRemovedCallback)
EndSyncLock
EndSub

PrivateSharedFunctionCreateReport()AsString
DimmyReportAsNewSystem.Text.StringBuilder()
myReport.Append("SalesReport<br/>")
myReport.Append("2005Q2Figures<br/>")
myReport.Append("SalesNERegion-$2million<br/>")
myReport.Append("SalesNWRegion-$4.5million<br/>")
myReport.Append("ReportGenerated:"&_
DateTime.Now.ToString()&"<br/>")
myReport.Append("ReportRemovedFromCache:"_
&_reportRemovedFromCache.ToString())
ReturnmyReport.ToString()
EndFunction

PublicSharedSubReportRemovedCallback(ByValkeyAsString,_
ByValvalueAsObject,ByValremovedReason_
AsCacheItemRemovedReason)
_reportRemovedFromCache=True
CacheReport()
EndSub
EndClass

如何:从ASP.NET缓存中删除项ASP.NET缓存中的数据是易失的,即不能永久保存。由于以下任一原因,缓存中的数据可能会自动移除:
缓存已满。

该项已过期。

依赖项发生更改。

有关更多信息,请参见ASP.NET缓存概述。
从缓存中移除项的具体方法由用于向缓存添加项的代码确定。有关更多信息,请参见如何:将项添加到缓存中。项从缓存中移除时会向您发出通知。有关更多信息,请参见如何:从缓存中移除项时通知应用程序。
除了允许从缓存中自动移除项之外,还可以显式移除项。
注意
如果调用Insert方法,并向缓存中添加与现有项同名的项,则将从缓存中删除该旧项。

从缓存中显式删除项

调用Remove方法,以传递要移除的项的键。 下面的示例演示如何移除键为MyData1的项。 VisualBasic 复制代码Cache.Remove("MyData1")


C#


复制代码

Cache.Remove("MyData1");


使用SqlCacheDependency类在ASP.NET中缓存

ASP.NET允许您使用
SqlCacheDependency类创建依赖于数据库中表或行的缓存项。当表中或特定行中发生更改时,带有依赖项的项便会失效,并会从缓存中移除。可以在MicrosoftSQLServer7.0、SQLServer2000和SQLServer2005中设置表的依赖项。如果您使用SQLServer2005,还可以设置特定记录的依赖项。

在某些方案中,使用带有SQL依赖项的缓存可显著提高应用程序的性能。例如,假定您正在构建一个从数据库显示产品信息的电子商务应用程序。如果不进行缓存,则每当用户要查看产品时,应用程序都必须从数据库请求数据。您可以在某一时刻将产品信息缓存一天,由于产品信息已经在内存中,因此可确保较快的响应时间,但是,当产品信息发生变化时,缓存的产品信息就会失去与数据库中数据的同步,且不同步的时间最长可达一天。

使用SQL缓存依赖项可以缓存产品信息,并创建一个数据库表或行更改的依赖项。当且仅当数据更改时,基于该数据的缓存项便会失效并会从缓存中移除。下次从缓存中请求该项时,如果该项不在缓存中,便可以再次向缓存中添加更新后的版本,并且可确保具有最新的数据。

SQL缓存依赖项还可用于页输出缓存。例如,可以创建一个名为ViewProduct.aspx的页,用于显示有关特定产品的信息。可以将该页的缓存策略设置为SQL依赖项,就如为手动添加到缓存中的项所设置的依赖项一样。该页便会一直存储在缓存中,直至所依赖的表或行发生更改为止。当数据发生更改时,便会重新创建页,并将新创建的页再次存储在输出缓存中。

有关更多信息,请参见
ASP.NET缓存概述。

功能

ASP.NETSQL缓存依赖项提供以下功能:

SQL缓存依赖项可用于应用程序缓存和页输出缓存。

可在SQLServer7.0及更高版本中使用SQL缓存依赖项。

可以在网络园(一台服务器上存在多个处理器)或网络场(多台服务器运行同一应用程序)中使用SQL缓存依赖项。

与SQL缓存依赖项关联的数据库操作比较简单,因此不会给服务器带来很高的处理成本。

在应用程序和SQLServer中配置SQL缓存依赖项不需要很精深的SQL知识。ASP.NET中包括可以自动执行此配置的工具。另外,还可以使用

SqlCacheDependencyAdmin类以编程方式配置SQL缓存依赖项。

SQLServer7.0和SQLServer2000实现

ASP.NET为SQLServer7.0和SQLServer2000的缓存依赖项实现了一个轮询模型。ASP.NET进程内的一个线程会以指定的时间间隔轮询SQLServer数据库,以确定数据是否已更改。如果数据已更改,缓存依赖项便会失效,并从缓存中移除。可以在Web.config文件中以声明方式指定应用程序中的轮询间隔,也可以使用
SqlCacheDependency类以编程方式指定此间隔。

对于SQLServer7.0和SQLServer2000,SQL缓存依赖项仅限于表级别的数据更改。可以将ASP.NET配置为轮询数据库来确定表中的更改,但不能确定特定行中的更改。

启用SQL缓存

为了在SQLServer7.0和SQLServer2000中使用SQL缓存依赖项,必须先将SQLServer配置为支持缓存依赖项。ASP.NET提供了一些实用工具,可用于配置SQLServer上的SQL缓存,其中包括一个名为Aspnet_regsql.exe的工具和
SqlCacheDependencyAdmin类。有关如何在SQLServer上启用SQL缓存依赖项的更多信息,请参见如何:使用缓存键依赖项缓存页输出。

SQLServer2005实现

SQLServer2005为缓存依赖项实现的模型不同于SQLServer7.0和SQLServer2000中的缓存依赖项模型。在SQLServer2005中,不需要执行任何特殊的配置步骤来启用SQL缓存依赖项。此外,SQLServer2005还实现了一种更改通知模型,可以向订阅了通知的应用程序服务器发送通知,而不是依赖早期版本的SQLServer中必需的轮询模型。

SQLServer2005缓存依赖项在接收通知的更改类型方面更具灵活性。SQLServer2005监控对特定SQL命令的结果集的更改。如果数据库中发生了将修改该命令的结果集的更改,依赖项便会使缓存的项失效。此功能使得SQLServer2005可以提供行级别的通知。

对用于测试更改的查询有一些要求。必须提供完全限定的表名,其中包括所有者名称(例如dbo.authors)。总之,SQL2005通知支持Select查询和存储过程,支持多个查询和嵌套查询,但不支持聚合操作(例如
COUNT(*))。有关SQLServer2005支持哪些查询以及通知规则的更多信息,请参见“SQLBooksOnline”(SQL联机丛书)中的主题“CreatingaQueryforNotification”(创建通知查询)。

在ASP.NET应用程序中配置SQL缓存

在对SQLServer7.0或SQLServer2000进行了缓存依赖项配置后,或是在SQLServer2005中创建了适当的命令依赖项后,就可以配置您的应用程序来使用SQL缓存依赖项,如同配置任何其他缓存依赖项一样。例如,可以在Web.config文件中创建一个缓存配置文件,然后在应使用SQL缓存依赖项的每个页中引用该缓存配置文件。还可以在通过
SqlCacheDependency类以编程方式启用SQL缓存依赖项后再使用它。有关更多信息,请参见如何:使用缓存键依赖项缓存页输出。

缓存ASP.NET页

ASP.NET使您可以缓存ASP.NET页所生成的部分响应或所有响应,在ASP.NET中将这种技术称为输出缓存。可以在发出请求的浏览器、响应请求的Web服务器以及请求或响应流中任何其他具有缓存功能的设备(如代理服务器)上缓存页。缓存为您提供了一个强有力的方式来提高Web应用程序的性能。缓存功能允许利用缓存满足对页的后续请求,这样就不需要再次运行最初创建该页的代码。对站点中访问最频繁的页进行缓存可以充分地提高Web服务器的吞吐量(通常以每秒的请求数计算)。

可以在页或配置文件中以声明方式或者通过编程方式使用缓存API指定缓存设置。有关更多信息,请参见设置页的可缓存性。

可以根据查询字符串参数值或窗体变量值(控件值)缓存页。必须通过使用
@OutputCache指令的
VaryByParam属性,显式启用基于这些类型的值的缓存。有关更多信息,请参见缓存页的多个版本。

当用户请求某一缓存页时,ASP.NET根据已经为该页定义的缓存策略确定其缓存输出是否仍有效。如果该输出有效,则将该缓存输出发送到客户端,并且不重新处理该页。ASP.NET允许您在此验证检查期间运行代码,以便可以编写用于检查页是否有效的自定义逻辑。有关更多信息,请参见如何:检查缓存页的有效性。

有时,缓存整个页是不切实际的,因为在每次请求时可能需要更改页的某些部分。在这些情况下,可以缓存页的一部分。ASP.NET提供了只缓存ASP.NET页的几部分的功能。有关更多信息,请参见缓存ASP.NET页的某些部分。

如何:以声明方式设置ASP.NET页的可缓存性

某页或用户控件的可缓存性指某页能否在其响应生命周期内缓存到某个设备上。这些设备包括发出请求的客户端(浏览器),响应请求的Web服务器,以及请求或响应流中任何具有缓存功能的设备(例如代理服务器)。

如果您在设计时知道某页需要什么样的可缓存性设置,您可以以声明方式设置可缓存性。该页将为所有请求使用相同的可缓存性设置。有关更多信息,请参见设置页的可缓存性。

以声明方式设置页的可缓存性

在页中包含
@OutputCache指令,并定义
Duration和
VaryByParam属性。

@OutputCache指令中包含
Location属性,并将其值定义为
OutputCacheLocation枚举中的下列值之一:Any、Client、Downstream、Server、ServerAndClient

None。

下面的代码演示如何将页的可缓存性设置为60秒:

<%@OutputCacheDuration="60"VaryByParam="None"%>



注意
默认设置为Any。如果未定义Location属性,则可以将页输出缓存在与响应有关的所有具有缓存功能的网络设备上。其中包括请求客户端、原服务器、以及响应通过的任何代理服务器。

使用缓存配置文件以声明方式设置页的可缓存性

在应用程序的Web.config文件中定义缓存配置文件,在配置文件中包括durationvaryByParam设置。

下面的
<caching>配置元素定义名为Cache30Seconds的缓存配置文件,它将在服务器上将页缓存30秒之久。

<caching>
<outputCacheSettings>
<outputCacheProfiles>
<addname="Cache30Seconds"duration="30"
varyByParam="none"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>


在使用配置文件的每个ASP.NET页中包含
@OutputCache指令,并将
CacheProfile属性设置为Web.config文件中定义的缓存配置文件的名称。

下面的代码指定页应当使用名为Cache30Seconds的缓存配置文件:

<%@OutputCacheCacheProfile="Cache30Seconds"%>


如何:以编程方式设置页的可缓存性页或用户控件的可缓存性指的是某一页是否能在该页的响应生命周期内缓存在某个设备上。缓存页的这些设备包括发出请求的浏览器,响应请求的Web服务器,以及请求或响应流中任何可执行缓存的设备,如代理服务器。
如果应用程序将根据运行时条件(如读取请求标头)确定可缓存性,您可以通过编程方式设置可缓存性。有关更多信息,请参见设置页的可缓存性。

以编程方式设置页的可缓存性

在页的代码中,调用Response对象的Cache属性的SetCacheability方法。 下面的代码将Cache-ControlHTTP标头设置为Public。 C# 复制代码Response.Cache.SetCacheability(HttpCacheability.Public); Response.Cache.SetCacheability(HttpCacheability.Public)

如果将
NoCache或
ServerAndNoCache传递到SetCacheability方法以防止请求的浏览器在它自己的历史记录文件夹中缓存某一页,那么任何时候当某个用户单击“后退”或“前进”按钮时,都会请求响应的新版本。通过调用

Cache属性的
SetAllowResponseInBrowserHistory方法,并且为allow参数传递true值,您可以按条件重写此行为。

如果将可缓存性设置为除NoCacheServerAndNoCache之外的任何值,ASP.NET将忽略由
SetAllowResponseInBrowserHistory方法设置的值。

如何:设置ASP.NET页缓存的过期时间值

若要导致某一页添加到输出缓存中,需要为该页建立到期策略。这可以通过以声明方式或编程方式来实现。

以声明方式为页设置输出缓存到期时间


@OutputCache指令包括在您要缓存其响应的ASP.NET页(.aspx文件)中。将

Duration属性设置为一个正数值,将
VaryByParam属性设置为一个值。


注意
默认情况下,@OutputCache指令将
Cache-Control标头设置为Any

例如,下面的@OutputCache指令将页的到期时间设置为60秒:

<%@OutputCacheDuration="60"VaryByParam="None"%>



注意
在使用@OutputCache指令时,必须包括一个VaryByParam属性,否则将出现分析器错误。如果不希望使用
VaryByParam属性提供的功能,请将它的值设置为“None”。有关更多信息,请参见缓存页的多个版本。

以编程方式为页设置输出缓存到期时间

在该页的代码中,在
Response对象的
Cache属性中设置该页的到期策略。


注意
如果以编程方式设置页的到期时间,则您还必须为缓存的页设置Cache-Control标头。为此,请调用
SetCacheability方法并向其传递
HttpCacheability枚举值Public

下面的代码示例设置与前面过程中的@OutputCache指令相同的缓存策略。

C#


复制代码

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(true);


VisualBasic


复制代码

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
Response.Cache.SetCacheability(HttpCacheability.Public)
Response.Cache.SetValidUntilExpires(True)

当缓存页到期时,以后对该页的请求将导致动态生成的响应。会在指定的持续时间内缓存该响应页。

如何:检查缓存页的有效性

用户请求缓存页时,ASP.NET根据您在该页中定义的缓存策略来确定缓存输出是否仍然有效。如果缓存输出有效,则将输出发送到客户端,并且不重新处理该页。但是,ASP.NET提供了使用验证回调在该验证检查期间运行代码的功能,因此您可以编写自定义逻辑来检查该页是否有效。利用验证回调,可以使在使用缓存依赖项的正常进程之外的缓存页无效。

以编程方式检查缓存页的有效性

定义
HttpCacheValidateHandler类型的事件处理程序,并包括检查缓存页响应的有效性的代码。

验证处理程序必须返回下列
HttpValidationStatus值之一:

Invalid指示缓存页无效,将从缓存中移除该页,并且该请求将被作为缓存未命中处理。

IgnoreThisRequest导致将请求视为缓存未命中处理。因此,将重新处理该页,但不会使缓存页无效。

Valid指示缓存页有效。

下面的代码示例阐释名为ValidateCacheOutput的验证处理程序,该处理程序确定查询字符串变量status包含值“invalid”还是“ignore”。如果状态值为“invalid”,则该方法返回
Invalid,并且使该页在缓存中无效。如果状态值为“ignore”,则该方法返回IgnoreThisRequest,并且该页仍保留在缓存中,但为该请求生成一个新响应。

C#


复制代码

publicstaticvoidValidateCacheOutput(HttpContextcontext,Objectdata,
refHttpValidationStatusstatus)
{
if(context.Request.QueryString["Status"]!=null)
{
stringpageStatus=context.Request.QueryString["Status"];

if(pageStatus=="invalid")
status=HttpValidationStatus.Invalid;
elseif(pageStatus=="ignore")
status=HttpValidationStatus.IgnoreThisRequest;
else
status=HttpValidationStatus.Valid;
}
else
status=HttpValidationStatus.Valid;
}


VisualBasic


复制代码

PublicSharedSubValidatePage(ByValcontextAsHttpContext,_
ByValdataAs[Object],ByRefstatusAsHttpValidationStatus)
IfNot(context.Request.QueryString("Status")IsNothing)Then
DimpageStatusAsString=context.Request.QueryString("Status")

IfpageStatus="invalid"Then
status=HttpValidationStatus.Invalid
ElseIfpageStatus="ignore"Then
status=HttpValidationStatus.IgnoreThisRequest
Else
status=HttpValidationStatus.Valid
EndIf
Else
status=HttpValidationStatus.Valid
EndIf
EndSub


从其中一个页生命周期事件(如页的
Load事件)中调用
AddValidationCallback方法,将您在步骤1中定义的事件处理程序作为第一个参数传递。

下面的代码示例将ValidateCacheOutput方法设置为验证处理程序。

C#


复制代码

protectedvoidPage_Load(objectsender,EventArgse)
{
Response.Cache.AddValidationCallback(
newHttpCacheValidateHandler(ValidateCacheOutput),
null);
}


VisualBasic


复制代码

ProtectedSubPage_Load(ByValsenderAsObject,_
ByValeAsSystem.EventArgs)HandlesMe.Load

Response.Cache.AddValidationCallback(_
NewHttpCacheValidateHandler(AddressOfValidatePage),Nothing)
EndSub


缓存ASP.NET页的某些部分有时缓存整个页是不现实的,因为页的某些部分可能在每次请求时都需要更改。在这些情况下,只能缓存页的一部分。执行此操作有两个选项:控件缓存和缓存后替换。
在控件缓存(也称为片段缓存)中,可以通过创建用户控件来包含缓存的内容,然后将用户控件标记为可缓存来缓存部分页输出。该选项允许缓存页中的特定内容,而在每次都重新创建整个页。例如,如果创建的页显示大量动态内容(如股票信息),但也有某些部分是静态的(如每周摘要),则可以在用户控件中创建这些静态部分并将用户控件配置为缓存。
缓存后替换与控件缓存正好相反。它对页进行缓存,但是页中的某些片段是动态的,因此不会缓存这些片段。例如,如果创建的页在设定的时间段内完全是静态的(例如新闻报道页),可以设置为缓存整个页。如果为缓存的页添加旋转广告横幅,则在页请求之间,广告横幅不会变化。然而,使用缓存后替换,可以对页进行缓存,但可以将特定部分标记为不可缓存。在本例中,将广告横幅标记为不可缓存。它们将在每次页请求时动态创建,并添加到缓存的页输出中。有关缓存后替换的更多信息,请参阅动态更新缓存页的部分。

控件缓存

通过创建用户控件来缓存内容,可以将页上需要花费宝贵的处理器时间来创建的某些部分(例如数据库查询)与页的其他部分分离开。只需占用很少服务器资源的部分可以在每次请求时动态生成。 在标识了要缓存的页的部分,并创建了用以包含这些部分中的每个部分的用户控件后,您必须确定这些用户控件的缓存策略。您可以使用@OutputCache指令,或者在代码中使用PartialCachingAttribute类,以声明的方式为用户控件设置这些策略。 例如,如果在用户控件文件(.ascx文件)的顶部包括下面的指令,则该控件的一个版本将在输出缓存中存储120秒。 <%@OutputCacheDuration="120"VaryByParam="None"%>

若要在代码中设置缓存参数,可以在用户控件的类声明中使用一个属性。例如,如果在类声明的元数据中包括下面的属性,则该内容的一个版本将在输出缓存中存储120秒:

C#


复制代码

[PartialCaching(120)]
publicpartialclassCachedControl:System.Web.UI.UserControl
{
//ClassCode
}


VisualBasic


复制代码

<PartialCaching(120)>_
PartialClassCachedControl
InheritsSystem.Web.UI.UserControl
'ClassCode
EndClass

有关可在页输出中设置的属性的更多信息,请参阅
@OutputCache主题。有关如何开发用户控件的更多信息,请参见
ASP.NETWeb服务器控件概述。


注意
由于可在页上嵌套用户控件,您还可以嵌套已放置到输出缓存中的用户控件。可以为页和嵌套的用户控件指定不同的缓存设置。

以编程方式引用缓存的用户控件

在以声明的方式创建可缓存的用户控件时,可以包括一个
ID属性,以便以编程方式引用该用户控件实例。但是,在代码中引用用户控件之前,必须验证在输出缓存中是否存在该用户控件。缓存的用户控件只在首次请求时动态生成;在指定的时间到期之前,从输出缓存满足所有的后续请求。确定用户控件已实例化后,可以从包含页以编程方式操作该用户控件。例如,如果通过声明方式将
SampleUserControl的ID分配给用户控件,则可以使用下面的代码检查它是否存在。

C#


复制代码

protectedvoidPage_Load(objectsender,EventArgse)
{
if(SampleUserControl!=null)
//PlacecodemanipulatingSampleUserControlhere.
}


VisualBasic


复制代码

ProtectedSubPage_Load(ByValsenderAsObject,_
ByValeAsSystem.EventArgs)HandlesMe.Load
IfSampleUserControl<>NothingThen
'PlacecodemanipulatingSampleUserControlhere.
EndIf
EndSub


以不同的持续时间缓存页和用户控件

可以为页和页上的用户控件设置不同的输出缓存持续时间值。如果页的输出缓存持续时间长于用户控件的输出缓存持续时间,则页的输出缓存持续时间优先。例如,如果页的输出缓存设置为100秒,而用户控件的输出缓存设置为50秒,则包括用户控件在内的整个页将在输出缓存中存储100秒,而与用户控件较短的时间设置无关。

下面的代码示例演示了当页的缓存持续时间长于用户控件的缓存持续时间时的效果。该页配置为缓存100秒。

C#


复制代码

<%@Pagelanguage="C#"%>
<%@Registertagprefix="SampleControl"tagname="Time"src="uc01.ascx"%>
<%@OutputCacheduration="100"varybyparam="none"%>

<SampleControl:Timerunat="server"/><br/><br/><br/>

Thispagewasmostrecentlygeneratedat:<p>

<%DateTimet=DateTime.Now.ToString();
Response.Write(t);%>


VisualBasic


复制代码

<%@Pagelanguage="VB"%>
<%@Registertagprefix="SampleControl"tagname="Time"src="uc01.ascx"%>
<%@OutputCacheduration="100"varybyparam="none"%>

<SampleControl:Timerunat="server"/><br/><br/><br/>

Thispagewasmostrecentlygeneratedat:<p>
<%DimtAsDateTime=DateTime.Now.ToString()
Response.Write(t)%>

下面的代码示例演示了包括在页中的用户控件。控件的缓存持续时间设置为50秒。

C#


复制代码

<%@Controllanguage="C#"%>
<%@OutputCacheduration="50"varybyparam="none"%>

Thisusercontrolwasmostrecentlygeneratedat:<p>
<%DateTimet=DateTime.Now.ToString();
Response.Write(t);%>


VisualBasic


复制代码

<%@Controllanguage="VB"%>
<%@OutputCacheduration="50"varybyparam="none"%>

Thisusercontrolwasmostrecentlygeneratedat:<p>
<%DimtAsDateTime=DateTime.Now.ToString()
Response.Write(t)%>

不过,如果页的输出缓存持续时间比用户控件的输出缓存持续时间短,则即使已为某个请求重新生成该页的其余部分,也将一直缓存用户控件直到其持续时间到期为止。例如,如果页的输出缓存设置为50秒,而用户控件的输出缓存设置为100秒,则页的其余部分每到期两次,用户控件才到期一次。

下面的代码演示了一个页的标记,该页中包含的用户控件的缓存持续时间长于该页的缓存持续时间。该页配置为缓存50秒。

C#


复制代码

<%@Pagelanguage="C#"%>
<%@Registertagprefix="SampleControl"tagname="Time"src="uc2.ascx"%>
<%@OutputCacheduration="50"varybyparam="none"%>

<SampleControl:Timerunat="server"/><br/><br/><br/>

Thispagewasmostrecentlygeneratedat:<p>
<%DateTimet=DateTime.Now.ToString();
Response.Write(t);%>


VisualBasic


复制代码

<%@Pagelanguage="VB"%>
<%@Registertagprefix="SampleControl"tagname="Time"src="Uc2.ascx"%>
<%@OutputCacheduration="50"varybyparam="none"%>

<SampleControl:Timerunat="server"/><br/><br/><br/>

Thispagewasmostrecentlygeneratedat:<p>
<%DimtAsDateTime=DateTime.Now.ToString()
Response.Write(t)%>

下面的代码演示了包括在页中的用户控件。控件的缓存持续时间设置为100秒。

C#


复制代码

<%@Controllanguage="C#"%>
<%@OutputCacheduration="100"varybyparam="none"%>

Thisusercontrolwasmostrecentlygeneratedat:<p>

<%DateTimet=DateTime.Now.ToString();
Response.Write(t);%>


VisualBasic


复制代码

<%@Controllanguage="VB"%>
<%@OutputCacheduration="100"varybyparam="none"%>

Thisusercontrolwasmostrecentlygeneratedat:<p>
<%DimtAsDateTime=DateTime.Now.ToString()
Response.Write(t)%>

缓存页的多个版本有时,您可能希望缓存某页,但是会基于请求为该页创建不同的版本。例如,根据查询字符串中传递的值,该页可能具有不同的输出。
ASP.NET允许在输出缓存中缓存同一页的多个版本。输出缓存可能会因下列因素而异:
初始请求(HTTPGET)中的查询字符串。

回发时传递的控制值(HTTPPOST值)。

随请求传递的HTTP标头。

发出请求的浏览器的主版本号。

该页中的自定义字符串。在这种情况下,可以在Global.asax文件中创建自定义代码以指定该页的缓存行为。

可以通过以下两种方法来缓存页输出的多个版本:使用@OutputCache指令的属性以声明方式,或者使用HttpCachePolicy类的属性和方法以编程方式。
@OutputCache指令包括四个可用来缓存页输出的多个版本的属性:
VaryByParam属性可用来使缓存输出因查询字符串而异。

VaryByControl属性可用来使缓存输出因控制值而异。

VaryByHeader属性可用来使缓存输出因请求的HTTP标头而异。

VaryByCustom属性可用来使缓存输出因浏览器类型或您定义的自定义字符串而异。

注意
您必须在任何@OutputCache指令中包括VaryByParam属性或VaryByControl属性。但是,如果您不需要使缓存输出因控制值或参数而异,则可以定义值为NoneVaryByParam
HttpCachePolicy类提供两个属性和一个方法,您可以通过它们以编程方式指定与以声明方式所能设置的缓存配置相同的缓存配置。使用VaryByParams和VaryByHeaders属性可以分别指定查询字符串参数和标头名称作为缓存策略改变依据。使用SetVaryByCustom方法可以定义要作为输出缓存改变依据的自定义字符串。

如何:使用缓存键依赖项缓存页输出有时,当缓存中的某一项被移除时,您可能需要从输出缓存中移除一页。例如,您可能使用一页来显示放置在应用程序缓存中并供多个页使用的占用大量进程的报告。当该报告已更改或已从缓存中移除时,您希望将页输出也从缓存中移除,因为该报告不再有效。为此,可使缓存的页输出依赖于其他缓存项。

注意
通过调用RemoveOutputCacheItem方法,可显式移除输出缓存中的任何页。可以从Global.asax文件、自定义ASP.NET服务器控件或页中执行此操作,具体取决于应用程序的需要。

使缓存的页输出依赖于另一缓存项

在页中,以声明方式或编程方式指定缓存设置。有关更多信息,请参见如何:设置ASP.NET页缓存的过期时间值、设置页的可缓存性和缓存页的多个版本。

在页代码中调用AddCacheItemDependency方法。将创建依赖项的缓存项的名称作为cacheKey参数传递。
下面的代码示例演示如何在名为ProcessIntensiveReport的项上设置依赖项。当此项被修改或移除时,将从缓存中移除页输出。
C#

复制代码protectedvoidPage_Load(objectsender,EventArgse)
{
Response.AddCacheItemDependency("ProcessIntensiveReport");

//Setadditionalpropertiestoenablecaching.
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60)); Response.Cache.SetCacheability(HttpCacheability.Public); Response.Cache.SetValidUntilExpires(true);}


VisualBasic


复制代码

ProtectedSubPage_Load(ByValsenderAsObject,ByValeAsSystem.EventArgs)HandlesMe.Load
Response.AddCacheItemDependency("ProcessIntensiveReport")

'Setadditionalpropertiestoenablecaching.
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60)) Response.Cache.SetCacheability(HttpCacheability.Public) Response.Cache.SetValidUntilExpires(True)EndSub



注意
不能在ASP.NET用户控件中调用AddCacheItemDependency方法。不过,在指定
@OutputCache指令的任何用户控件中,都可以创建描述缓存键依赖项的
CacheDependency对象,并将其分配给
UserControl对象的
Dependency属性。

如何:使用文件依赖项缓存页输出

有时候,您可能需要在文件发生更改时从输出缓存中移除某一页。例如,您可能有这样一页:该页从生成XML文件作为输出且占用大量进程的报告中获取其内容。仅当XML文件发生更改时,才需要重新处理该页。要将重新处理限制为仅在需要的时候进行,可以使页的缓存策略依赖于单个文件。如有必要,可以使缓存页依赖于多个文件。


注意
通过调用
RemoveOutputCacheItem方法,可显式移除输出缓存中的任何页。可以从Global.asax文件、自定义ASP.NET服务器控件或页中执行此操作,具体取决于应用程序的需要。

使缓存页输出依赖于一个文件

以声明方式或编程方式指定缓存页输出的设置。有关更多信息,请参见如何:设置ASP.NET页缓存的过期时间值、设置页的可缓存性和缓存页的多个版本。

在页代码中调用
AddFileDependency方法。将创建依赖项的文件的路径作为方法的
filename参数传递。

下面的代码示例在TextFile1.txt文件上设置一个文件依赖项。当文件发生更改时,将从缓存中移除页输出。

C#


复制代码

protectedvoidPage_Load(objectsender,EventArgse)
{
stringfileDependencyPath=Server.MapPath("TextFile1.txt");
Response.AddFileDependency(fileDependencyPath);

//Setadditionalpropertiestoenablecaching.
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60)); Response.Cache.SetCacheability(HttpCacheability.Public); Response.Cache.SetValidUntilExpires(true);}


VisualBasic


复制代码

ProtectedSubPage_Load(ByValsenderAsObject,_
ByValeAsEventArgs)HandlesMe.Load
DimfileDependencyPathAsString=_
Server.MapPath("TextFile1.txt")
Response.AddFileDependency(fileDependencyPath)

'Setadditionalpropertiestoenablecaching.
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60)) Response.Cache.SetCacheability(HttpCacheability.Public) Response.Cache.SetValidUntilExpires(True)EndSub



注意
不能从ASP.NET用户控件使用这些方法。但是,在指定
@OutputCache指令的任何用户控件中,您都可以创建一个文件依赖项,并将其分配给

Dependency属性。

使缓存页输出依赖于文件组

以声明方式或编程方式指定缓存页输出的设置。有关更多信息,请参见如何:设置ASP.NET页缓存的过期时间值、设置页的可缓存性和缓存页的多个版本。

在页代码中,创建一个包含该页所要依赖的文件的路径的
String数组或
ArrayList。

调用
AddFileDependencies方法,并将数组作为
filenames参数传递。

下面的代码示例创建包含TextFile1.txt和XMLFile1.xml文件的文件路径的字符串数组,并使页输出依赖于这两个文件。如果修改了其中任何一个文件,将从缓存中移除页输出。

C#


复制代码

protectedvoidPage_Load(objectsender,EventArgse)
{
string[]fileDependencies;
stringfileDependency1=Server.MapPath("TextFile1.txt");
stringfileDependency2=Server.MapPath("XMLFile1.xml");
fileDependencies=newString[]{fileDependency1,
fileDependency2};
Response.AddFileDependencies(fileDependencies);
}


VisualBasic


复制代码

ProtectedSubPage_Load(ByValsenderAsObject,ByValeAsSystem.EventArgs)HandlesMe.Load
DimfileDependencies()AsString
DimfileDependency1AsString=Server.MapPath("TextFile1.txt")
DimfileDependency2AsString=Server.MapPath("XMLFile1.xml")
fileDependencies=NewString(){fileDependency1,_
fileDependency2}
Response.AddFileDependencies(fileDependencies)
EndSub


CacheItemRemovedCallback委托定义在从Cache移除缓存项时通知应用程序的回调方法。
命名空间:System.Web.Caching
程序集:System.Web(在system.web.dll中)


语法
VisualBasic(声明)PublicDelegateSubCacheItemRemovedCallback(_
keyAsString,_
valueAsObject,_
reasonAsCacheItemRemovedReason_
)


VisualBasic(用法)

DiminstanceAsNewCacheItemRemovedCallback(AddressOfHandlerMethod)


C#

publicdelegatevoidCacheItemRemovedCallback(
stringkey,
Objectvalue,
CacheItemRemovedReasonreason
)


C++

publicdelegatevoidCacheItemRemovedCallback(
String^key,
Object^value,
CacheItemRemovedReasonreason
)


J#

/**@delegate*/
publicdelegatevoidCacheItemRemovedCallback(
Stringkey,
Objectvalue,
CacheItemRemovedReasonreason
)


JScript

JScript支持使用委托,但不支持进行新的声明。

参数

key
从缓存中移除的键。

value
与从缓存中移除的键关联的
Object项。

reason
CacheItemRemovedReason枚举指定的、从缓存移除项的原因。



示例

下面的代码示例演示一个页面,该页面为用户显示缓存中某项的赋值,当该项从缓存中移除时将通知用户。它创建RemovedCallback方法,该方法使用
CacheItemRemovedCallback委托的签名,以在缓存项被移除时通知用户并且使用CacheItemRemovedReason枚举告诉用户该项被移除的原因。此外,它使用

Cache.Item属性将对象添加到缓存中并检索这些对象的值。在AddItemToCache方法中,它使用

Cache.Add方法向缓存中添加项。若要使用CacheItemRemovedCallback委托,您必须使用此方法或者

Cache.Insert方法向缓存中添加项,以便该项被移除时ASP.NET能自动调用正确的方法。自定义的
RemoveItemFromCache方法使用
Cache.Remove方法显式地从缓存中删除该项,这导致调用RemovedCallback方法。

VisualBasic


复制代码

<%@PageLanguage="VB"%>

<html>
<Scriptrunat=server>
ShareditemRemovedAsboolean=false
SharedreasonAsCacheItemRemovedReason
DimonRemoveAsCacheItemRemovedCallback

PublicSubRemovedCallback(kAsString,vAsObject,rAsCacheItemRemovedReason)
itemRemoved=true
reason=r
EndSub

PublicSubAddItemToCache(senderAsObject,eAsEventArgs)
itemRemoved=false

onRemove=NewCacheItemRemovedCallback(AddressOfMe.RemovedCallback)

If(IsNothing(Cache("Key1")))Then
Cache.Add("Key1","Value1",Nothing,DateTime.Now.AddSeconds(60),TimeSpan.Zero,CacheItemPriority.High,onRemove)
EndIf
EndSub

PublicSubRemoveItemFromCache(senderAsObject,eAsEventArgs)
If(NotIsNothing(Cache("Key1")))Then
Cache.Remove("Key1")
EndIf
EndSub
</Script>

<body>
<Formrunat="server">
<inputtype=submitOnServerClick="AddItemToCache"value="AddItemToCache"runat="server"/>
<inputtype=submitOnServerClick="RemoveItemFromCache"value="RemoveItemFromCache"runat="server"/>
</Form>
<%
If(itemRemoved)Then
Response.Write("RemovedCallbackeventraised.")
Response.Write("<BR>")
Response.Write("Reason:<B>"+reason.ToString()+"</B>")
Else
Response.Write("Valueofcachekey:<B>"+Server.HtmlEncode(CType(Cache("Key1"),String))+"</B>")
EndIf
%>
</body>
</html>


C#


复制代码

<html>
<Scriptrunat=serverlanguage="C#">
staticboolitemRemoved=false;
staticCacheItemRemovedReasonreason;
CacheItemRemovedCallbackonRemove=null;

publicvoidRemovedCallback(Stringk,Objectv,CacheItemRemovedReasonr){
itemRemoved=true;
reason=r;
}

publicvoidAddItemToCache(Objectsender,EventArgse){
itemRemoved=false;

onRemove=newCacheItemRemovedCallback(this.RemovedCallback);

if(Cache["Key1"]==null)
Cache.Add("Key1","Value1",null,DateTime.Now.AddSeconds(60),TimeSpan.Zero,CacheItemPriority.High,onRemove);
}

publicvoidRemoveItemFromCache(Objectsender,EventArgse){
if(Cache["Key1"]!=null)
Cache.Remove("Key1");
}
</Script>
<body>
<Formrunat="server">
<inputtype=submitOnServerClick="AddItemToCache"value="AddItemToCache"runat="server"/>
<inputtype=submitOnServerClick="RemoveItemFromCache"value="RemoveItemFromCache"runat="server"/>
</Form>
<%if(itemRemoved){
Response.Write("RemovedCallbackeventraised.");
Response.Write("<BR>");
Response.Write("Reason:<B>"+reason.ToString()+"</B>");
}
else{
Response.Write("Valueofcachekey:<B>"+Server.HtmlEncode(Cache["Key1"]asstring)+"</B>");
}
%>
</body>
</html>


JScript


复制代码

<html>
<Scriptrunat=serverlanguage="JScript">

staticvaritemRemoved:boolean=false;
staticvarreason:CacheItemRemovedReason;
varonRemove:CacheItemRemovedCallback=null;

publicfunctionRemovedCallback(k:String,v:Object,r:CacheItemRemovedReason){
itemRemoved=true;
reason=r;
}

publicfunctionAddItemToCache(sender:Object,e:EventArgs){
itemRemoved=false;

onRemove=this.RemovedCallback;

if(Cache["Key1"]==null)
Cache.Add("Key1","Value1",null,DateTime.Now.AddSeconds(10),TimeSpan.Zero,CacheItemPriority.High,onRemove);
}

publicfunctionRemoveItemFromCache(sender:Object,e:EventArgs){
if(Cache["Key1"]!=null)
Cache.Remove("Key1");
}
</Script>

<body>
<Formrunat="server">
<inputtype=submitOnServerClick="AddItemToCache"value="AddItemToCache"runat="server"/>
<inputtype=submitOnServerClick="RemoveItemFromCache"value="RemoveItemFromCache"runat="server"/>
</Form>
<%
if(itemRemoved){
Response.Write("RemovedCallbackeventraised.");
Response.Write("<BR>");
Response.Write("Reason:<B>"+reason+"</B>");
}
else{
Response.Write("Valueofcachekey:<B>"+Server.HtmlEncode(Cache["Key1"].ToString())+"</B>");
}
%>

</body>
</html>

CacheItemRemovedReason枚举指定从Cache对象移除项的原因。
命名空间:System.Web.Caching
程序集:System.Web(在system.web.dll中)


语法
VisualBasic(声明)PublicEnumerationCacheItemRemovedReason


VisualBasic(用法)

DiminstanceAsCacheItemRemovedReason


C#

publicenumCacheItemRemovedReason


C++

publicenumclassCacheItemRemovedReason


J#

publicenumCacheItemRemovedReason


JScript

publicenumCacheItemRemovedReason




成员

成员名称说明
DependencyChanged从缓存移除该项的原因是与之关联的缓存依赖项已更改。
Expired从缓存移除该项的原因是它已过期。
Removed该项是通过指定相同键的Insert方法调用或
Remove方法调用从缓存中移除的。
Underused之所以从缓存中移除该项,是因为系统要通过移除该项来释放内存。


备注

CacheItemRemovedCallback委托使用此枚举来通知ASP.NET应用程序从
Cache移除对象的时间和原因。

TopicLocation
Howto:NotifyanApplicationWhenanItemIsRemovedfromthe
Cache
BuildingASP.NETWebApplications
Howto:NotifyanApplicationWhenanItemIsRemovedfromthe
Cache
BuildingASP.NETWebApplications
HOWTO:當項目從快取移除時告知應用程式建置ASP.NETWeb應用程式


示例

下面的代码示例演示共享Boolean属性itemRemoved、共享CacheItemRemovedReason枚举对象
reason和CacheItemRemovedCallback委托onRemove。后者可用在

Insert或
Add方法调用中。它还定义了方法RemovedCallback,该方法的签名与
CacheItemRemovedCallback委托匹配。当RemovedCallback方法被调用时,它将
itemRemoved属性值更改为true,并将reason属性值赋给由
CacheItemRemovedReason
枚举提供的原因。

VisualBasic


复制代码

ShareditemRemovedAsboolean=false
SharedreasonAsCacheItemRemovedReason
DimonRemoveAsCacheItemRemovedCallback

PublicSubRemovedCallback(kAsString,vAsObject,rAsCacheItemRemovedReason)
itemRemoved=true
reason=r
EndSub


C#


复制代码

staticboolitemRemoved=false;
staticCacheItemRemovedReasonreason;
CacheItemRemovedCallbackonRemove=null;

publicvoidRemovedCallback(Stringk,Objectv,CacheItemRemovedReasonr){
itemRemoved=true;
reason=r;
}


JScript


复制代码

staticvaritemRemoved:boolean=false;
staticvarreason:CacheItemRemovedReason;
varonRemove:CacheItemRemovedCallback=null;

publicfunctionRemovedCallback(k:String,v:Object,r:CacheItemRemovedReason){
itemRemoved=true;
reason=r;
}

CacheDependency类在存储于ASP.NET应用程序的Cache对象中的项与文件、缓存键、文件或缓存键的数组或另一个CacheDependency对象之间建立依附性关系。CacheDependency类监视依附性关系,以便在任何这些对象更改时,该缓存项都会自动移除。
命名空间:System.Web.Caching
程序集:System.Web(在system.web.dll中)


语法
VisualBasic(声明)PublicClassCacheDependency
ImplementsIDisposable


VisualBasic(用法)

DiminstanceAsCacheDependency


C#

publicclassCacheDependency:IDisposable


C++

publicrefclassCacheDependency:IDisposable


J#

publicclassCacheDependencyimplementsIDisposable


JScript

publicclassCacheDependencyimplementsIDisposable




备注

如果向缓存添加一个依赖于另一个对象(如文件或文件数组)的项,则在该对象更改时会自动从缓存中移除该依赖项。例如,假设您基于XML文件中的数据创建一个
DataSet对象。可以利用使DataSet依赖于XML文件的
CacheDependency对象将该DataSet添加到缓存中。如果该XML文件发生更改,则
DataSet从缓存中移除。

可以用
Add和
System.Web.Caching.Cache.Insert方法向应用程序缓存中添加具有依赖项的项。不能使用

Item属性向缓存中添加具有依赖项的项。

若要设置依赖项,请创建CacheDependency类的一个实例,指定项依赖的文件、键或目录,然后将该依赖项传递给
Add
System.Web.Caching.Cache.Insert方法。CacheDependency实例可以表示单个文件或目录、一组文件或目录,或者带有一系列缓存键的一组文件或目录(这些缓存键表示
Cache对象中存储的其他项)。



示例

下面的代码示例演示如何使用
HasChanged属性来确定CacheDependency是否在对
Cache中某项的上一个请求之后已更改。将传入start参数的
dt值设置为
DateTime.Now。

VisualBasic


复制代码

'Insertthecacheitem.
DimdepAsNewCacheDependency(fileName,dt)
myCache.Insert("key","value",dep)

'CheckwhetherCacheDependency.HasChangedistrue.
Ifdep.HasChangedThen
Response.Write("<p>Thedependencyhaschanged.")
Else
Response.Write("<p>Thedependencyhasnotchanged.")
EndIf


C#


复制代码

//Insertthecacheitem.
CacheDependencydep=newCacheDependency(fileName,dt);
cache.Insert("key","value",dep);

//CheckwhetherCacheDependency.HasChangedistrue.
if(dep.HasChanged)
Response.Write("<p>Thedependencyhaschanged.");
elseResponse.Write("<p>Thedependencyhasnotchanged.");


J#


复制代码

//Insertthecacheitem.
CacheDependencydep=newCacheDependency(fileName,dt);
cache.Insert("key","value",dep);

//CheckwhetherCacheDependency.HasChangedistrue.
if(dep.get_HasChanged()){
get_Response().Write("<p>Thedependencyhaschanged.");
}
else{
get_Response().Write("<p>Thedependencyhasnotchanged.");
}

AggregateCacheDependency类注意:此类在.NETFramework2.0版中是新增的。
组合ASP.NET应用程序的Cache对象中存储的项和CacheDependency对象的数组之间的多个依赖项。无法继承此类。
命名空间:System.Web.Caching
程序集:System.Web(在system.web.dll中)


语法
VisualBasic(声明)PublicNotInheritableClassAggregateCacheDependency
InheritsCacheDependency


VisualBasic(用法)

DiminstanceAsAggregateCacheDependency


C#

publicsealedclassAggregateCacheDependency:CacheDependency


C++

publicrefclassAggregateCacheDependencysealed:publicCacheDependency


J#

publicfinalclassAggregateCacheDependencyextendsCacheDependency


JScript

publicfinalclassAggregateCacheDependencyextendsCacheDependency




备注

AggregateCacheDependency类监视依赖项对象的集合,以便在任何依赖项对象更改时,该缓存项都会自动移除。数组中的对象可以是
CacheDependency对象、SqlCacheDependency对象、从
CacheDependency派生的自定义对象或这些对象的任意组合。

AggregateCacheDependency类与CacheDependency类的不同之处在于前者允许您将不同类型的多个依赖项与单个缓存项关联。例如,如果您创建一个从SQLServer数据库表和XML文件导入数据的页,则可创建一个
SqlCacheDependency对象来表示数据库表的依赖项,以及一个CacheDependency来表示XML文件的依赖项。可创建
AggregateCacheDependency类的一个实例,将每个依赖项添加到该类中,而不是为每个依赖项调用
Cache.Insert方法。然后,可使用单个
Insert调用使该页依赖于AggregateCacheDependency实例。



示例

下面的代码示例使用AggregateCacheDependency类将名为XMLDataSet的

DataSet添加到依赖于文本文件和XML文件的缓存中。

VisualBasic


复制代码

'Whenthepageisloaded,usethe
'AggregateCacheDependencyclasstomake
'acacheditemdependentontwofiles.

SubPage_Load(senderAsObject,eAsEventArgs)
DimSourceAsDataView

Source=Cache("XMLDataSet")

IfSourceIsNothing
DimDSAsNewDataSet
DimFSAsFileStream
DimReaderAsStreamReader
DimtxtDepAsCacheDependency
DimxmlDepAsCacheDependency
DimAsAggregateCacheDependency

FS=NewFileStream(Server.MapPath("authors.xml"),FileMode.Open,FileAccess.Read)
Reader=NewStreamReader(FS)
DS.ReadXml(Reader)
FS.Close()

Source=newDataView(ds.Tables(0))
'CreatetwoCacheDependencyobjects,onetoa
'textfileandtheothertoanXMLfile.
'CreateaCacheDependencyarraywiththese
'twoobjectsasitemsinthearray.
txtDep=NewCacheDependency(Server.MapPath("Storage.txt"))
xmlDep=NewCacheDependency(Server.MapPath("authors.xml"))
DimDepArray()AsCacheDependency={txtDep,xmlDep}

'CreateanAggregateCacheDependencyobjectand
'usetheAddmethodtoaddthearraytoit.
aggDep=NewAggregateCacheDependency()
aggDep.Add(DepArray)

'CalltheGetUniqueIdmethodtogenerate
'anIDforeachdependencyinthearray.
msg1.Text=aggDep.GetUniqueId()

'Addthenewdatasettothecachewith
'dependenciesonbothfilesinthearray.
Cache.Insert("XMLDataSet",Source,aggDep)
IfaggDep.HasChanged=TrueThen
chngMsg.Text="Thedependencychangedat:"&DateTime.Now

Else
chngMsg.Text="Thedependencychangedlastat:"&aggDep.UtcLastModified.ToString()
EndIf

cacheMsg1.Text="Datasetcreatedexplicitly"
Else
cacheMsg1.Text="Datasetretrievedfromcache"
EndIf

MyLiteral.Text=Source.Table.TableName
MyDataGrid.DataSource=Source
MyDataGrid.DataBind()
EndSub

PublicSubbtn_Click(senderAsObject,eAsEventArgs)

If(MyTextBox.Text=String.Empty)Then
msg2.Text="Youhavenotchangedthetextfile."
Else
msg2.Text="Youadded"&MyTextBox.Text&"."

'CreateaninstanceoftheStreamWriterclass
'towritetexttoafile.
DimswAsStreamWriter
sw=File.CreateText(Server.MapPath("Storage.txt"))

'Addsometexttothefile.
sw.Write("Youentered:")
sw.WriteLine(MyTextBox.Text)

'Writearbitraryobjectstothefileasneeded.
sw.Write("Textaddedat:")
sw.WriteLine(DateTime.Now)
sw.WriteLine("-------------------")
sw.Close()
EndIf
EndSub





















                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: