ASP.NET状态管理之六(缓存Cache)

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

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

设计 Cache 类是为了便于使用。您可以将项放置在 Cache 中,并在以后使用简单的键/值对来检索这些项。

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

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

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

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

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

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

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

通过键和值直接设置项向缓存添加项
通过指定项的键和值,像将项添加到字典中一样将其添加到缓存中。 
下面的代码示例将名为 CacheItem1 的项添加到 Cache 对象中:
Cache["CacheItem1"] = "Cached Item 1";

通过使用 Insert 方法将项添加到缓存中
调用 Insert 方法,传递要添加的项的键和值。 
下面的代码示例添加名为 CacheItem2 的字符串:
Cache.Insert("CacheItem2", "Cached Item 2");

通过指定依赖项向缓存添加项
调用 Insert 方法,将CacheDependency 对象的一个实例传递给该方法 
下面的代码示例添加名为 CacheItem3 的项,该项依赖于缓存中名为 CacheItem2 的另一个项:
string[] dependencies = { "CacheItem2" };
Cache.Insert("CacheItem3", "Cached Item 3",
    new System.Web.Caching.CacheDependency(null, dependencies));

下面的代码示例演示将名为 CacheItem4 的项添加到缓存中,并且在名为 XMLFile.xml 的文件上设置文件依赖项:
Cache.Insert("CacheItem4", "Cached Item 4",
    new System.Web.Caching.CacheDependency(
    Server.MapPath("XMLFile.xml")));

下面的代码示例演示如何创建多个依赖项。它向缓存中名为 CacheItem1 的另一个项添加键依赖项,向名为 XMLFile.xml 的文件添加文件依赖项。
System.Web.Caching.CacheDependency dep1 = 
    newSystem.Web.Caching.CacheDependency(Server.MapPath("XMLFile.xml"));
string[] keyDependencies2 = { "CacheItem1" };
System.Web.Caching.CacheDependency dep2 = 
    new System.Web.Caching.CacheDependency(null,keyDependencies2);
System.Web.Caching.AggregateCacheDependency aggDep = 
    new System.Web.Caching.AggregateCacheDependency();
aggDep.Add(dep1);
aggDep.Add(dep2);
Cache.Insert("CacheItem5", "Cached Item 5", aggDep);

将设有过期策略的项添加到缓存中
调用 Insert 方法,将绝对过期时间或弹性过期时间传递给该方法。 
下面的代码示例将有一分钟绝对过期时间的项添加到缓存中:
Cache.Insert("CacheItem6", "Cached Item 6",
    null, DateTime.Now.AddMinutes(1d), 
    System.Web.Caching.Cache.NoSlidingExpiration);

下面的代码示例将有 10 分钟弹性过期时间的项添加到缓存中:
Cache.Insert("CacheItem7", "Cached Item 7",
    null, System.Web.Caching.Cache.NoAbsoluteExpiration,
    new TimeSpan(0, 10, 0));

将设有优先级设置的项添加到缓存中
调用 Insert 方法,从CacheItemPriority 枚举中指定一个值。 
下面的代码示例将优先级值为 High 的项添加到缓存中:
Cache.Insert("CacheItem8", "Cached Item 8",
    null, System.Web.Caching.Cache.NoAbsoluteExpiration,
    System.Web.Caching.Cache.NoSlidingExpiration,
    System.Web.Caching.CacheItemPriority.High, null);

使用 Add 方法向缓存添加项
调用 Add 方法,它返回一个表示项的对象。 
下面的代码示例向缓存添加名为 CacheItem9 的项,同时将变量 CachedItem9 的值设置为已添加的项。
string CachedItem9 = (string)Cache.Add("CacheItem9",
    "Cached Item 9", null,
    System.Web.Caching.Cache.NoAbsoluteExpiration,
    System.Web.Caching.Cache.NoSlidingExpiration, 
    System.Web.Caching.CacheItemPriority.Default,
    null);

缓存依赖例题:
我们在一页面建立1个按钮,查看CACHE是否存在
在窗体启动时我们创建CACHE,名称="txt2",数值=数据集ds
该CACHE与myfile.xml相关联,当myfile.xml文件变化时,txt2CACHE就被自动删除

privatevoid Page_Load(object sender, System.EventArgs e)
  {
   if( !IsPostBack  )
   {
   string FilePath=MapPath("myfile.xml");
   SqlConnection con=newSqlConnection("Uid=sa;database=pubs;");
   SqlDataAdapter da =new SqlDataAdapter("select * fromauthors",con);
   DataSet ds=new DataSet();
   da.Fill(ds);
   System.Web.Caching.CacheDependency CacheDependencyXmlFile=newSystem.Web.Caching.CacheDependency(FilePath);
   Cache.Insert("txt2",ds ,CacheDependencyXmlFile);
   }
  }

为了监视pubs数据库authors表的变化
我们可以在pubs数据库authors表建立触发器
一旦authors表中发生增加,删除,修改数据时,触发器会自动修改文件myfile.xml
一旦myfile.xml文件变化,txt2CACHE就被系统自动删除

CREATETRIGGER tr_authors
ON authors
FOR INSERT, UPDATE ,delete
AS 
declare @cmd nvarchar(4000)
select @cmd='bcp "select convert(nvarchar(30),Getdate(),13)" queryoutD:\cache\WebCache\myfile.xml -c -Sglc2403 -Usa -P'
exec master..xp_cmdshell @cmd
GO

private void QueryButton_Click(object sender, System.EventArgs e)
{
if ( Cache["txt2"]!=null)
{
 Response.Write("exists");
}
else
{
 Response.Write("not exists");
}
}

首先我们点按钮,显示Cache["txt2"]存在
现在我们去表authors中任意修改一数据,再点按钮,显示Cache["txt2"]不存在拉

以上我们是把CACHE是和一个文件相关联,我们还可以把CACHE和文件组关联,建立依赖
以下我们把CACHE和2个文件(myfile.xml,myfile1.xml)关联,一旦文件组中其中任意一文件变化,Cache会把"txt2"项的数据从CACHE中删除

string[]FilePath=newString[]{MapPath("myfile.xml"),MapPath("myfile1.xml")};
System.Web.Caching.CacheDependencyCacheDependencyXmlFile=new                    System.Web.Caching.CacheDependency(FilePath);
string CacheVaule="a";
Cache.Insert("txt2", CacheVaule ,CacheDependencyXmlFile);

缓存依赖可以是文件,还可以是其他对象的键
下面的代码说明缓存Cache["txt2"]既依赖文件myfile.xml,又依赖缓存中的Cache["txt"],只要这2者任意一样改变,缓存Cache["txt2"]就会清除

Cache["txt"]= "b";
string[] FilePath=new String[]{ MapPath("myfile.xml")};
string[] dependencyKey=new String[]{"txt"};
SqlConnection con=new SqlConnection("Uid=sa;database=pubs;");
SqlDataAdapter da =new SqlDataAdapter("select * from authors",con);
DataSet ds=new DataSet();
da.Fill(ds);
System.Web.Caching.CacheDependency CacheDependencyXmlFile=
          newSystem.Web.Caching.CacheDependency(FilePath,dependencyKey);
Cache.Insert("txt2",ds ,CacheDependencyXmlFile);

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

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

从 ASP.NET 缓存中删除项
ASP.NET 缓存中的数据是易失的,即不能永久保存。由于以下任一原因,缓存中的数据可能会自动移除:
1.缓存已满。
2.该项已过期。
3.依赖项发生更改。

从缓存中显式删除项
调用 Remove 方法,以传递要移除的项的键。 
下面的示例演示如何移除键为 MyData1 的项。
Cache.Remove("MyData1");

从缓存中移除项时通知应用程序
在大多数缓存方案中,当从缓存中移除项后,直到再次需要此项时,才需要将其放回缓存中。典型的开发模式是在使用项之前始终检查该项是否已在缓存中。如果项位于缓存中,则可以使用。如果不在缓存中,则应再次检索该项,然后将其添加回缓存。

但是,在某些情况下,如果从缓存中移除项时通知应用程序,可能非常有用。例如,您可能具有一个缓存的报告,创建该报告需花费大量的时间进行处理。当该报告从缓存中移除时,您希望重新生成该报告,并立即将其置于缓存中,以便下次请求该报告时,用户不必等待对此报告进行处理。

为了在从缓存中移除项时能够发出通知,ASP.NET 提供了 CacheItemRemovedCallback 委托。该委托定义编写事件处理程序时使用的签名,当对从缓存中移除项进行响应时会调用此事件处理程序。ASP.NET 还提供 CacheItemRemovedReason 枚举,用于指定移除缓存项的原因。

通常,通过在管理尝试检索的特定缓存数据的业务对象中创建处理程序,来实现回调。例如,您可能有一个ReportManager 对象,该对象具有两种方法,即GetReport 和 CacheReport。GetReport 报告方法检查缓存以查看报告是否已缓存;如果没有,该方法将重新生成报告并将其缓存。CacheReport方法具有与 CacheItemRemovedCallback 委托相同的函数签名;从缓存中移除报告时,ASP.NET 会调用 CacheReport 方法,然后将报告重新添加到缓存中。

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

static System.Web.Caching.CacheItemRemovedReason reason;
System.Web.Caching.CacheItemRemovedCallback onRemove = null;

publicvoid RemovedCallback(String k, Object v,System.Web.Caching.CacheItemRemovedReason r)
{
 itemRemoved = true;
 reason = r;
}

onRemove= new System.Web.Caching.CacheItemRemovedCallback (this.RemovedCallback);
Cache.Insert("txt",ds,null,
System.Web.Caching.Cache.NoAbsoluteExpiration,
System.Web.Caching.Cache.NoSlidingExpiration,
System.Web.Caching.CacheItemPriority.Default,onRemove);

由于任何原因从Cache中移除时,将调用 RemovedCallback 方法

ASP.NET状态管理之六(缓存Cache)相关推荐

  1. ASP.NET状态管理之一(概括篇)

    每次将网页发送到服务器时,都会创建网页类的一个新实例.在传统的Web编程中,这通常意味着在每一次往返行程中,与该页及该页上的控件相关联的所有信息都会丢失.例如,如果用户将信息输入到文本框,该信息将在从 ...

  2. ASP.NET状态管理之五(Cookie)

    Cookie 提供了一种在 Web 应用程序中存储用户特定信息的方法. 例如,当用户访问您的站点时,您可以使用 Cookie 存储用户首选项或其他信息.当该用户再次访问您的网站时,应用程序便可以检索以 ...

  3. ASP.NET 状态管理概述(MSDN)

    每次将网页发送到服务器时,都会创建网页类的一个新实例.在传统的 Web 编程中,这通常意味着在每一次往返行程中,与该页及该页上的控件相关联的所有信息都会丢失.例如,如果用户将信息输入到文本框,该信息将 ...

  4. ASP.NET状态管理之三(隐藏域HiddenField)

    ASP.NET 允许您将信息存储在 HiddenField 控件中,此控件将呈现为一个标准的 HTML 隐藏域. 隐藏域在浏览器中不以可见的形式呈现,但您可以就像对待标准控件一样设置其属性. 当向服务 ...

  5. ASP.NET 状态管理概览

    页面每次被回传到服务器的时候都会创建 Web 页面类的一个新实例.在传统的 Web 开发中,这意味着在每次回传的过程中,页面中所有与页面和控件相关联的信息都将被丢失.例如,如果用户在一个文本框中输入了 ...

  6. 【转】【C#.NET】ASP.NET状态管理之一:Cookie

    [C#.NET]ASP.NET状态管理之一:Cookie 状态管理是你对同一页或不同页的多个请求维护状态和页信息的过程.与所有基于 HTTP 的技术一样,Web 窗体页是无状态的,这意味着它们不自动指 ...

  7. ASP.NET状态管理

    第一部分:页面状态介绍 Http协议----"无状态协议" Web服务器每分钟对上千个用户进行管理的一种方式就是执行所谓的"无状态"链接.只要有一个希望浏览器返 ...

  8. ASP.NET状态管理之十三(总结)

    状态管理是您对同一页或不同页的多个请求维护状态和页信息的过程.与所有基于 HTTP 的技术一样,Web 窗体页是无状态的,这意味着它们不自动指示序列中的请求是否全部来自相同的客户端,或者单个浏览器实例 ...

  9. ASP.NET状态管理详解,让你明明白白

    开发WinFrom的程序员可能不会在意维护应用程序的状态,因为WinFrom本身就在客户端运行,可以直接在内存中维护其应用程序状态.但ASP.NET应用程序在服务器端运行,客户端使用无状态的http协 ...

最新文章

  1. Docker部署Jmeter 性能监控服务(常用命令)
  2. RabbitMQ消息队列系列教程(一)认识RabbitMQ
  3. hdu4920 矩阵乘法%3
  4. 4.1.8 文件保护
  5. photoshop cs3反应慢的原因
  6. Oracle不带传出参数的存储过程创建及调用
  7. 云端的SRE发展与实践
  8. 无法定位程序输入点 _ZdaPvj 于动态链接库 libstdc++-6.dll
  9. SPRO事务码里如何开发一个新的customizing activity
  10. 鸿蒙不是安卓也不是Linux
  11. 高性能自旋锁 MCS Spinlock 的设计与实现(来自IBM)
  12. 玩转接口测试,那些必备的技能
  13. 伙伴系统二叉树可视化笔记
  14. layui树形表格treetable
  15. 正点原子Linux开发板实现WiFi开机自动连接
  16. 电子与电工技术实验——集成运算放大器的应用
  17. 一文了解数据分析师与商业分析师的区别(一)
  18. 计算机平时测试零分,计算机二级最全攻略 就快考试了不看等什么呢!
  19. 单道批-多道批-分时-实时
  20. AutoCAD选择对象后触发事件,加载和卸载

热门文章

  1. 第16届电源技术专题研讨会
  2. CCF201412-2 Z字形扫描(解法二)(100分)
  3. C/C++语法知识:typedef struct 用法详解
  4. Mac OS X下安装Java 7及配置Eclipse JDK
  5. 由Java说起:编程语言还需要开源吗?
  6. 教学思路SQL之入门习题《学员成绩》 三、多表复杂子查询
  7. 『遥かに仰ぎ、丽しの』游戏初回版特典原声集 GAME SP OST(下载、中日双语歌词)...
  8. USBCopyer(听说此款软件可以悄悄偷走你U盘的小电影)
  9. 五、C#入门—流程控制
  10. 初学java小白的疑惑梳理