C# 缓存技术

缓存主要是为了提高数据的读取速度。因为服务器和应用客户端之间存在着流量的瓶颈,所以读取大容量数据时,使用缓存来直接为客户端服务,可以减少客户端与服务器端的数据交互,从而大大提高程序的性能。

本章从缓存所在的命名空间“System.Web.Caching”开始,详细介绍框架提供的缓存类和操作方法,主要涉及简单数据的缓存、数据缓存依赖和数据库缓存依赖三个技术要点,最后演示一个完全使用缓存实现数据读取的实例。讲解流程如图16-1所示。

图16-1 缓存命名空间的讲解流程

16.1 System.Web.Caching简介

本节从缓存命名空间的总体简介和组成结构入手,从整体上对System.Web.Caching进行概述。

16.1.1 System.Web.Caching概述

System.Web.Caching是用来管理缓存的命名空间。缓存就是将服务器端的数据暂时保存在客户端,方便用户的读取。缓存命名空间的父级空间是“System.Web”,由此可以看出,缓存通常用于Web网站的开发,包括在B/S项目中的开发。缓存的设计主要是考虑到网络带宽可能会延缓数据的提交和回发,如果将数据保存在客户端,用户可以直接从客户端读取数据,这样数据就是从本地提取的,不会再受网络的影响。

System.Web.Caching命名空间提供与缓存有关的所有操作类,具体包括哪些类将在下一节详细介绍。

16.1.2 System.Web.Caching命名空间内的类组成

缓存命名空间主要提供三种操作:缓存数据对象、对象的缓存依赖和数据库的缓存依赖。其中缓存任何对象都使用一个类Cache,但当缓存发生改变时,普通对象和数据库对象的依赖处理不同。

图16-2罗列的是在三层结构中缓存的部署情况。两个依赖类CacheDependency和SqlCache Dependency主要更改发生变化的缓存数据,起到通知的作用。当数据没有被缓存时,使用Cache类进行添加。

下面根据图16-2的部署,来介绍图中使用的缓存类。这些类的说明如表16-1所示。

图16-2 三层结构中缓存的部署图

表16-1 缓存命名空间中的类及其说明




Cache


对缓存对象的编辑类,其操作包括缓存的增、删、改


CacheDependency


基本缓存对象的依赖,当基本对象发生变化时,更新缓存内容


SqlCacheDependency


数据库缓存对象的依赖,当数据库中的数据变化时,更新缓存内容

16.2 管理缓存的类:Cache类

Cache类用来存储数据对象,并提供方法对这些对象进行编辑。本节主要介绍Cache类包含的方法,以及如何使用这些方法实现数据对象的缓存。

16.2.1 功能说明

Cache类属于字典类,其根据一定的规则存储用户需要的数据,这些数据的类型不受限制,可以是字符串、数组、数据表、Dataset和哈希表等。

使用Cache类的优点是当缓存的数据发生变化时,Cache类会让数据失效,并实现缓存数据的重新添加,然后通知应用程序,报告缓存的及时更新。

16.2.2 语法定义

Cache类的语法定义如下:

public sealed class Cache : IEnumerable

通过其定义可以发现,Cache类是“sealed”定义的类,表示此类被密封,不能被继承。同时Cache类还继承了IEnumerable接口,表示允许对集合中的数据进行枚举操作。

缓存的生命周期随着应用程序域的活动结束而终止,也就是说只要应用程序域依然处于活动状态,缓存就会一直保持,因为每个应用程序域都会创建一个缓存实例。此实例的信息通过HttpContext对象的Cache属性或Page对象的Cache属性获取。

下面的代码演示如何将数组数据添加到缓存中:

ArrayList myarray = new ArrayList(); //创建数组数据

myarray.Add("1.学习园地");

myarray.Add("2.交流论坛");

myarray.Add("3.帮助");

Cache.Add("Category", myarray); //将数组添加到缓存中

16.2.3 方法详解

Cache类的方法主要提供对缓存数据的编辑操作,如增、删、改等。其中最常用的方法及其说明如表16-2所示。

表16-2 Cache类的主要方法及其说明




Add


将数据添加到Cache对象


Insert


Cache中插入数据项,可用于修改已经存在的数据缓存项


Remove


移除Cache对象中的缓存数据项


Get


Cache对象中获取指定的数据项,注意返回的是Object类型,需要进行类型转换


GetType


Cache对象中获取数据项的类型,判断数据类型后,方便进行转换


GetEnumerator


循环访问Cache对象中的缓存数据项。注意其返回类型是“IDictionaryEnumerator

技巧:要想修改缓存数据,只需要重新为缓存赋值即可。

最需要注意的是Add方法,其使用语法如下:

public Object Add (

string key,

Object value,

CacheDependency dependencies,

DateTime absoluteExpiration,

TimeSpan slidingExpiration,

CacheItemPriority priority,

CacheItemRemovedCallback onRemoveCallback

)

在使用Add方法时,以上7个参数是必需的,其代表意义如下:

— 参数“key”代表缓存数据项的键值,必须是唯一的。

— 参数“value”代表缓存数据的内容,可以是任意类型。

— 参数“dependencies”表示缓存的依赖项,也就是此项的更改意味着缓存内容已经过期。如果没有依赖项,可将此值设置为NULL。

— 参数“absoluteExpiration”是日期型数据,表示缓存过期的时间,.NET 2.0提供的缓存在过期后是可以使用的,能使用多长时间,就看这个参数的设置。

— 参数“slidingExpiration”的类型表示一段时间间隔,表示缓存参数将在多长时间以后被删除,此参数与absoluteExpiration参数相关联。

— 参数“priority”表示撤销缓存的优先值,此参数的值取自枚举变量“CacheItemPriority”,优先级低的数据项将先被删除。此参数主要用在缓存退出对象时。

— 参数“onRemoveCallback”表示缓存删除数据对象时调用的事件,一般用做通知程序。

下面的代码演示了如何应用Cache类的这些方法。在使用本代码时需要注意,代码中使用了Arraylist对象,所以需要添加对命名空间“System.Collections”的引用,同时使用Cache类别忘记了添加命名空间“System.Web.Caching”。

protected void Page_Load(object sender, EventArgs e)

{

ArrayList myarray = new ArrayList(); //创建数组数据

myarray.Add("1.学习园地");

myarray.Add("2.交流论坛");

myarray.Add("3.帮助");

//将数组添加到缓存中——使用Add方法

Cache.Add("Category", myarray, null, DateTime.Now.AddSeconds(60), TimeSpan.Zero, CacheItemPriority.Normal, null);

myarray[1] = "2.交流园地"; //修改数组数据

Cache.Insert("Category", myarray); //使用Insert方法修改缓存数据

string tmpStr = "这是一个临时数据";

Cache["tmpdata"] = tmpStr;

//使用Get方法获取缓存数据

Response.Write(Cache.Get("tmpdata").ToString()+"<br/>");/

Cache["tmpdata"] = "这是一个临时字符串"; //重新为缓存赋值的技巧

Response.Write(Cache.Get("tmpdata").ToString() + "<br/>");

//使用GetType方法判断缓存数据的类型

if (Cache["Category"].GetType().Name == "ArrayList")

Response.Write("类型是数组");

//使用GetEnumerator方法遍历缓存中的数据

IDictionaryEnumerator mycache = Cache.GetEnumerator();

while (mycache.MoveNext())

Response.Write(mycache.Value + "<br/>");

Cache.Remove("tmpdata");//使用Remove方法移除缓存的临时数据

}

技巧:在使用GetType方法时,如果要判断类型,需要使用Object.GetType().Name属性获取类型的名称。

上述代码的运行结果如下:

这是一个临时数据

这是一个临时字符串

类型是数组这是一个临时字符串

System.Collections.ArrayList

其中在读取类型为ArrayList的数据时,由于没有进行类型转换,所以取出的是类型为“System.Collections.ArrayList”的对象。本书会在本节最后的实例中介绍如何读取数组的详细内容。

16.2.4 属性详解

Cache类的属性主要用来获取缓存数据的一些基本信息,如缓存的项总数、指定位置的缓存项等。本书主要介绍两个属性:Count和Item。

Count用来获取缓存中所有的项的总数。使用方法如下:

Response.Write(Cache.Count);

Item用于返回指定项的内容,一般继承“IEnumerable”接口的类都有这样的属性,注意项需要使用“[ ]”包装。其使用方法如下:

Response.Write(Cache[“Category”].ToString());

16.2.5 典型应用:实现数据的缓存快速读取功能

Cache主要用来缓存使用频率高且不需经常更新的数据。本例实现一个目录列表的缓存。为了简便,列表的内容并没有从数据库中读取,而是保存在一个ArrayList对象中。

本例的目的是将目录列表填充到下拉框中,当缓存失效后,目录列表的内容为空。演示的步骤如下所述。

在VS2005中创建一个网站,命名为“CacheSample”。

打开默认生成的Default.aspx页,在其中添加一个下拉列表框和一个按钮。

按F7键切换到页面的代码视图。不要忘记对命名空间的引用,代码如下:

using System.Web.Caching;

using System.Collections;

在“Page_Load”事件中判断是否存在目录缓存,如果没有,则将目录添加到缓存中。详细代码如下所示,其中目录列表的保存时间是5秒。

protected void Page_Load(object sender, EventArgs e)

{

if (!Page.IsPostBack)

{

ArrayList myarray = new ArrayList();//假设ArrayList的内容来自数据库

myarray.Add("古代历史");

myarray.Add("当代文学");

myarray.Add("流行小说");

myarray.Add("武侠小说");

if (Cache["Categorys"] == null) //判断是否存在缓存

{

//如果缓存不存在,则添加——保存时间是5秒

Cache.Add("Categorys", myarray, null, DateTime.Now.AddSeconds(5),

TimeSpan.Zero, CacheItemPriority.Normal, null);

}

}

}

回到设计视图,双击按钮控件,切换到按钮的事件代码中。

在按钮的双击事件中,需要判断是否有目录的缓存,有则在下拉框中显示目录内容,没有则清空下拉框。详细代码如下:

protected void Button1_Click(object sender, EventArgs e)

{

if (Cache["Categorys"] != null) //判断缓存是否失效

{

//如果没有失效,则取出缓存的列表,注意类型的转换。

DropDownList1.DataSource = (ArrayList)Cache["Categorys"];

DropDownList1.DataBind();

}

else

{

DropDownList1.Items.Clear(); //如果已经失效,则清空列表

}

}

按Ctrl+S组合键保存所有的代码,再按F5键运行程序。在5秒以内如果单击按钮,则正常显示目录列表,如果超过5秒,则缓存对象已经不存在,所以下拉列表框的内容为空。

本节主要介绍了Cache类的使用方法,其中并没有涉及缓存依赖内容,即当实际数据改变时,缓存是否随着改变。下一节将通过学习“CacheDependency”类了解缓存依赖的详细实现。

时间: 2024-11-25 14:20:06

C# 缓存技术的相关文章

分布式缓存技术redis学习系列(三)——redis高级应用(主从、事务与锁、持久化)

上文<详细讲解redis数据结构(内存模型)以及常用命令>介绍了redis的数据类型以及常用命令,本文我们来学习下redis的一些高级特性. 回到顶部 安全性设置 设置客户端操作秘密 redis安装好后,默认情况下登陆客户端和使用命令操作时不需要密码的.某些情况下,为了安全起见,我们可以设置在客户端连接后进行任何操作之前都要进行密码验证.修改redis.conf进行配置. [[email protected] ~]# vi /usr/local/redis/etc/redis.conf ###

分布式缓存技术redis学习系列(一)——redis简介以及linux上的安装

redis简介 redis是NoSQL(No Only SQL,非关系型数据库)的一种,NoSQL是以Key-Value的形式存储数据.当前主流的分布式缓存技术有redis,memcached,ssdb,mongodb等.既可以把redis理解为理解为缓存技术,因为它的数据都是缓存在内从中的:也可以理解为数据库,因为redis可以周期性的将数据写入磁盘或者把操作追加到记录文件中.而我个人更倾向理解为缓存技术,因为当今互联网应用业务复杂.高并发.大数据的特性,正是各种缓存技术引入最终目的. 关于r

如何正确使用缓存技术

缓存技术是用来提升程序运行性能的常见手段,如你所见, 阿里巴巴.新浪微博.美团网等互联网龙头企业都是用缓存技术来提升自己家网站的性能.然而,任何事物都有两面性, 缓存技术使用得当带来的好处自然不言而喻, 但是如果使用不当, 产生的副作用也够让人喝一壶的. 我们写服务器程序时,使用缓存的目的无非就是减少数据库访问次数降低数据库的压力和提升程序的响应时间, 然而根据具体的使用场景又可以派生出无数种情况, 比如说 程序频繁读取数据库, 但是查询获得的结果却总是相同的,这部分相同的结果是不是可以放入缓存

Redis缓存技术学习系列之邂逅Redis

??作为一个反主流的开发者,在某种程度上,我对传统关系型数据库一直有点"讨厌",因为关系型数据库实际上和面向对象思想是完全冲突的,前者建立在数学集合理论的基础上,而后者则是建立在软件工程基本原则的基础上.虽然传统的ORM.序列化/反序列化在一定程度上解决了这种冲突,但是软件开发中关于使用原生SQL语句还是使用ORM框架的争论从来没有停止过.可是实际的业务背景中,是完全无法脱离数据库的,除非在某些特定的场合下,考虑到信息安全因素而禁止开发者使用数据库,在主流技术中数据库是一个非常重要的组

(转)java缓存技术,记录

http://blog.csdn.net/madun/article/details/8569860 最近再ITEYE上看到关于讨论JAVA缓存技术的帖子比较多,自己不懂,所以上网大概搜了下,找到一篇,暂作保存,后面如果有用到可以参考.此为转贴,帖子来处:http://cogipard.info/articles/cache-static-files-with-jnotify-and-ehcache 介绍 JNotify:http://jnotify.sourceforge.net/,通过JNI

硬盘缓存技术DiskLruCache技术&lt;笔记&gt;

防止多图OOM的核心解决思路就是使用LruCache技术,但LruCache只是管理了内存中图片的存储与释放,如果图片从内存中被移除的话,那么又需要从网络上重新加载一次,这显然非常耗时.因此Google又提供了一套硬盘缓存的解决方案:DiskLruCache(非Google官方编写,但获得官方认证).一般来说新闻类App从网络获取到数据后都会存入到本地缓存中,因此即使手机在没有网络的情况下依然能够加载出以前浏览过的新闻.使用的缓存技术自然是DiskLruCache.以网易新闻为例,它的Andro

PHP 缓存技术

PHP缓存包括PHP编译缓存和PHP数据缓存两种. PHP是一种解释型语言,属于边编译边运行的那种.这种运行模式的优点是程序修改很方便,但是运行效率却很低下. PHP编译缓存针对这种情况做改进处理,使得PHP语言只要运行一次,就可以把程序的编译结果缓存起来. PHP编译缓存: 目前最常见的PHP编译缓存工具有:APC,Accelerator,xcache(国产)等. PHP是一种解释型语言,在PHP语言执行代码的时候,需要下面两步: 1.编译过程.PHP读取文件,并编译该文件,然后生成能够在Ze

ASP.NET 缓存技术分析

缓存功能是大型网站设计一个很重要的部分.由数据库驱动的Web应用程序,如果需要改善其性能,最好的方法是使用缓存功能.可能的情况下尽量使用缓 存,从内存中返回数据的速度始终比去数据库查的速度快,因而可以大大提供应用程序的性能.毕竟现在内存非常便宜,用空间换取时间效率应该是非常划算的.尤 其是对耗时比较长的.需要建立网络链接的数据库查询操作等. 对于web页面的缓存,WebForm与ASP.NET MVC有不同的语法.在WebForm中, <%@ OutputCache Duration="6

PHP缓存技术

全页面静态化缓存也就是将页面全部生成html静态页面,用户访问时直接访问的静态页面,而不会去走php服务器解析的流程.此种方式,在CMS系统中比较常见,比如dedecms:一种比较常用的实现方式是用输出缓存:Ob1.全页面静态化缓存也就是将页面全部生成html静态页面,用户访问时直接访问的静态页面,而不会去走php服务器解析的流程.此种方式,在CMS系统中比较常见,比如dedecms:一种比较常用的实现方式是用输出缓存:Ob_start()******要运行的代码*******$content

强大的Spring缓存技术(上)

缓存是实际工作中非常常用的一种提高性能的方法, 我们会在许多场景下来使用缓存. 本文通过一个简单的例子进行展开,通过对比我们原来的自定义缓存和 spring 的基于注释的 cache 配置方法,展现了 spring cache 的强大之处,然后介绍了其基本的原理,扩展点和使用场景的限制.通过阅读本文,你应该可以短时间内掌握 spring 带来的强大缓存技术,在很少的配置下即可给既有代码提供缓存能力. 概述 Spring 3.1 引入了激动人心的基于注释(annotation)的缓存(cache)