System.Web.Caching

来源:互联网 发布:java sock 读byte 编辑:程序博客网 时间:2024/06/05 00:31

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

System.Web.Caching概述

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

     System.Web.Caching命名空间提供了与缓存有关的所有操作类。

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

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

    两个依赖类CacheDependency和SqlCacheDependency主要更改发送变化的缓存数据,起到通知作用。当数据没有被缓存时,是用Cache类进行添加。

缓存命名空间中的类及其说明:

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

CacheDependency : 基本缓存对象的依赖,当基本对象发送变化时,更新缓存内存

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

 

管理缓存的类: Cache类

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

功能说明

Cache类属于字典类,其根据一定的规则存储用户需要的数据,这些数据的类型不受限制,可以是字符串、数组、数据表、DataSet和哈希表等。缓存中的对象以键值的方式存储在一个字典类型的对象中,其中值是被存储的对象,键是一个具有描述性的字符串。

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

语法定义

public sealed class Cache: IEnumerable

通过其定义可以发现,Cache类继承了IEnumerable接口,表示允许对集合中的数据进行枚举操作。

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

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

ArrayList myarray = new ArrayList();   //创建数组数据myarray.Add("1.学习园地");myarray.Add("2.交流学习");myarray.Add("3.帮助");Cache.Add("Category",myarray);   //将数组添加到缓存中。

方法详解

Cache类的方法主要提供了对缓存数据的编辑操作,如增、删、改等。其中最常用的方法及其说明如下:

Add : 将数据添加到Cache对象

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

Remove : 除移Cache对象的缓存数据项

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

GetType : 从Cache对象中获取指定的类型,判断数据类型后,方便进行转换

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

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

 

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

public Object Add{

    string key,

    Object value,

    CacheDependency dependencies,

    DateTime absoluteExpiration,

    TimeSpan slidingExpiration,

    CacheItemPriority priority,

    CacheItemRemovedCallback onRemoveCallback

}

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

 参数“Key”代表缓存数据项的键值,必须是唯一的(key是一个字符串,表示在Cache字典中键的名字)。

参数“value”代表缓存数据的内容(任何类型的对象),可以是任意类型。

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

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

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

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

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

 

CacheItemPriority解释: 

namespace System.Web.Caching
{
    // 摘要:
    //     指定 System.Web.Caching.Cache 对象中存储的项的相对优先级。
    public enum CacheItemPriority
    {
        // 摘要:
        //     在服务器释放系统内存时,具有该优先级级别的缓存项最有可能被从缓存删除。
        Low = 1,
        //
        // 摘要:
        //     在服务器释放系统内存时,具有该优先级级别的缓存项比分配了 System.Web.Caching.CacheItemPriority.Normal
        //     优先级的项更有可能被从缓存删除。
        BelowNormal = 2,
        //
        // 摘要:
        //     在服务器释放系统内存时,具有该优先级级别的缓存项很有可能被从缓存删除,其被删除的可能性仅次于具有 System.Web.Caching.CacheItemPriority.Low
        //     或 System.Web.Caching.CacheItemPriority.BelowNormal 优先级的那些项。这是默认选项。
        Normal = 3,
        //
        // 摘要:
        //     缓存项优先级的默认值为 System.Web.Caching.CacheItemPriority.Normal。
        Default = 3,
        //
        // 摘要:
        //     在服务器释放系统内存时,具有该优先级级别的缓存项被删除的可能性比分配了 System.Web.Caching.CacheItemPriority.Normal
        //     优先级的项要小。
        AboveNormal = 4,
        //
        // 摘要:
        //     在服务器释放系统内存时,具有该优先级级别的缓存项最不可能被从缓存删除。
        High = 5,
        //
        // 摘要:
        //     在服务器释放系统内存时,具有该优先级级别的缓存项将不会被自动从缓存删除。但是,具有该优先级级别的项会根据项的绝对到期时间或可调整到期时间与其他项一起被移除。
        NotRemovable = 6,
    }
}

 

重载Insert方法的语法实例如下:

1、向缓存插入一个键/值对,其他参数使用默认值:Cache.Insert(Key,Value);

2、向缓存中插入一个带有依赖的键/值对,其他参数使用默认值;Cache.Insert(key,value,dependencies);

如果想查看这个方法的效果,下面语句

Cache["Category"] = myarray;

将其替换为:

Cache.Insert("Category",myarray);

 

下面的代码演示了如何应用Cache类的这些方法。在使用本代码时需要注意,使用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”的对象。

 

属性详解

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

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

Repsonse.Write(Cache.Count);

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

Response.Write(Cache["Category"].ToString());

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

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

在“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 Button_Click(object sender,EventArgs e)

{

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

      {

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

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

          DropDownList1.DataBind();

     }

     else

     {

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

     }

}
 运行程序,在5秒以内如果单击按钮,则正常显示目录列表,如果超过5秒,则缓存对象已经不存在,所以下拉列表框的内容为空。这个例子主要介绍了Cache类的使用方法,其中并没有涉及缓存依赖的内容,即当实际数据改变时,缓存是否随着改变。

 

缓存依赖类:CacheDependency类

    CacheDependency类是架设在Cache类和实际数据之间的桥梁。下面详细介绍如何利用CacheDependency类实现数据缓存的及时更新。

 CacheDependency类被称为是缓存依赖类,其具体意义表现在当缓存对象的实际数据发生改变时,它能及时通知缓存对象。例如缓存对象“Category”保存的是一个XML文件的数据,如果XML文件发生了变化,那么系统通过CacheDependency类就会及时更新缓存对象“Category”的内容,这样就能保证用户读取的永远是最新的数据。

语法定义

public class CacheDependency: IDisposable

其中继承了接口“IDisposable”,此接口主要用来定义释放分配的托管资源的方法。继承此接口必须实现方法Dipose,以实现资源的释放。

CacheDependency类的构造函数实现了8个重载,下面的代码列出了重载的函数,并详细说明了个函数的参数。了解这些函数就可以知道CacheDependency究竟能为缓存带来什么优势。

//假设缓存的来源是当前目录下地data.xml文件

//缓存依赖的文件路径

CacheDependency mydep = new CacheDependency("data.xml");

 

//缓存依赖的文件可以有多个

CacheDependency mydep1 = new CacheDependency(new string[] {"data.xml","data1.xml"});

也可以这样:先定义一个包含一个或多个文件路径的字符串数组,CacheDependency类的构造函数可以接收数组作为参数,如下:

string[] fileDependsArray = {Server.MapPath("data.xml"),Server.MapPath("data1.xml")};

CacheDependency mydep1 = new CacheDependency(fileDependsArray);

 

//检查缓存依赖更改的依据时间

CacheDependency mydep2 = new CacheDependency("data.xml",DateTime.Now);

//检查多个依赖文件更改的依据时间

CacheDependency mydep3 = new CacheDependecy(new string[] {"data.xml","data1.xml"},DataTime.Now);

//检查依赖多个文件,也依赖多个缓存键值

CacheDependency mydep4 = new CacheDependecy(new string[]{"data.xml","data1.xml"},new string[]{"Category","Categroy2"});

//关联依赖,还可以依赖另一个文件缓存依赖

CacheDependency mydep5 = new CacheDependency()

 

方法和属性
虽然CacheDependency类完成了很重要的功能,但其组成结构却比较简单,主要有两个属性和一个方法。

1、属性“HasChanged”: 判断CacheDependency对象是否已更改

2、属性“UtcLastModified” : 返回上次依赖项的修改日期

3、方法“Dispose” : 释放CacheDependency对象所占有的资源。因为缓存类继承了接口“IDisposable”,所以必须实现次方法。


用CacheDependency获取最新的数据

在Page_Load事件中书写生成缓存的代码。详细内容如下:

private static CacheDependency mydepen;protected void Page_Load(object sender,EventArgs e){    if(!IsPostBack)    {        //创建XML数据源         DataSet myds = new DataSet();         //数据源来自文件data.xml         myds.ReadXml(this.MapPath(Request.ApplicationPath + @"/data.xml"));         //判断是否存在缓存         if(Cache["BOOKS"]==null)        {          //创建缓存依赖            mydepn = new CacheDependecny(this.MapPath(Request.ApplicaitonPath + @"/data.xml"));          //添加缓存项            Cache.Add("BOOKS",myds,mydepen,DeteTime.Now.AddSecond(10),TimeSpan.Zero,CacheItemPriority.Normal,null);          }    }}"Button1_Click"事件内书写的详细代码如下: protected void Button1_Click(object sender,EventArgs e){    //判断缓存是否发生了变化    if(mydepen.HasChanged)    {       Repsonse.Write("Sorry,数据发生了变化,上次修改时间是:" + mydepen.UtcLastModifed);    }    //判断缓存项是否还存在     if(Cache["BOOKS"]==null)    {        //重新设置缓存项         DataSet myds = new DataSet();        myds.ReadXml(this.MapPath(Request.ApplicationPath + @"/data.xml"));        mydepen = new CacheDependency(this.MapPath(Request.ApplicationPath + @"/data.xml"));        Cache.Add("BOOKS",myds,mydepen,DateTime.Now.AddSeconds(10),TimeSpan.Zero,CacheItemPriority.Normal,null);    }    GridView1.DataSource = Cache["BOOKS"];    GridView1.DataBind();}

注意:当XML文件发生改变后,其实缓存依赖和缓存项都被移除了,必须重新定义。

程序正常运行后,在后台修改XML文件的内容,然后点击按钮,则出现更改数据的提示,同时GridView显示了新的内容。 

 

数据库缓存依赖类:SqlCacheDependency类

数据库缓存依赖主要解决的是当数据库的内容发生改变时,如何及时通知缓存,并更新缓存中的数据问题。SqlCacheDependency类的使用需要结合SQL Server 2005数据库,目前还没有Oracle数据库的缓存依赖。

SqlCacheDependency(string database,string table)

其中参数一代表要启用的数据库,参数二表示缓存的表。在实际使用过程中,只需要指明缓存的数据库和表即可。

 

 

Session和Cache的区别

以前实现数据的缓存有很多种方法,有客户端的Cookie,有服务端的Session和Application。其中Cookie是保存在客户端的一组数据,主要用来保存用户名等个人信息。Session则保存对话信息。Applicatioin则是保存在整个应用程序范围内的信息,相当于全局变量。通常使用最频繁的Session,那么Session和Cache又有什么区别呢?

1、最大的区别是Cache提供缓存依赖来更新数据,而Seesion只能依靠定义的缓存时间来判断缓存数据是否有效。

2、即使应用程序终止,只要Cache.Add方法定义的缓存时间未过期,下次开动应用程序时,缓存的数据依然存在。而Session缓存只是存在一次会话中,会话结束后,数据也就失效了。

3、Session容易丢失,导致数据的不确定性,而Cache不会出现这种情况。

4、由于Session是每次会话就被加载,所以不适宜存放大量信息,否则会导致服务器的性能降低。而Cache则主要用来保存大容量信息,如果数据库中的多个表。

为了提高Cache的有效利用率,建议对于不经改动的数据使用Cache.

 

Asp.Net使用Cache
Cache 即高速缓存 ,我想很多人对他的第一印象一定像我一样,感觉他一定能提高系统得性能和运行速度。的确。Net推出cache的初衷确实是这样的。那么cache是如何提高系统性能与运行速度呢?是不是在任何情况下用cache都能提高性能?是不是cache用的越多就越好呢?我在近期开发的项目中有所体会,写下来当作总结也希望能跟大家一起探讨探讨,有错误的地方希望大家批评指正。
1.       Cache 是如何工作的。

l         Cache 是分配在服务器上的一个公共的内存片。

所谓公共指的cache只要一创建是任何一个客户端浏览器都可以通过后台代码访问到它,它面向的是所有用户,相对而言session也是服务器上的一段内存,但他面向的是单个用户。它是服务器的一段内存块,也就是说每个cache一经创建就占用了服务器资源的。所以从这点来说我们就可以说:并不是cache越多越好。

l         cache 是有时间限制的,超过了服务器设定的过期时间,它就会被服务器回收。

l         c.cache 可以存放任何对象


2.       Cache 如何创建以及如何销毁。

l         创建cache

在。Net环境下通过Cache.Insert(string key,object o)方法创建。其中key 代表cache的ID,o代表存到cache里的对象。

l         销毁cache.

通过方法Cache.Remove(string key)其中key 代表cache的 ID.

l         调用cache.

Cache支持装箱/拆箱操作。如你可以把一个DataSet对象ds通过Cache.Insert(“dsCache”,ds)的方式存到Cache中,可以通过拆箱操作 DataSet ds = (DataSet)Cache[“dsCache”]来访问它。

 

 


3.       什么时候用cache.

Cache 一般用于数据较固定,用的较频繁的地方。例如可以把进销存系统中可以把产品信息存入cache,在用户调用产品信息时通过调用cache即可,这样从很大程度上减少了用户与数据库的交互,提高了系统的性能。反之,cache不适合用在数据变动快,使用范围很窄的地方。例如把一个具体采购单存入 cache中。


4.       cache 调用注意事项。

Cache是有时间限制的。超过了服务器设置的过期时间,就会被服务器回收。当cache被回收后对应的内存块就会被清空,再次通过cache[“cachekey”]访问对象时返回的就是null值。所以以下这种调用就会出现异常

DataSet ds = (DataSet)Cache[“cacheds”];

DataRow dr = ds.Table[0].Row[0];  //出错,ds为null值,不存在表0。

正确的写法应该是:

DataSet ds

If(Cache[“cacheds”] != null)

{

ds = (DataSet)Cache[“cacheds”];

}

Else

{

ds= GetDsFromDataBase();

}


 


 


DataRow dr = ds.Table[0].Row[0];

原创粉丝点击