当前位置: 首页 > 编程日记 > 正文

System.Web.Caching.Cache类 缓存 各种缓存依赖

原文:System.Web.Caching.Cache类 缓存 各种缓存依赖

Cache类,是一个用于缓存常用信息的类。HttpRuntime.Cache以及HttpContext.Current.Cache都是该类的实例。

一、属性

属性说明
Count获取存储在缓存中的项数。
EffectivePercentagePhysicalMemoryLimit获取在 ASP.NET 开始从缓存中移除项之前应用程序可使用的物理内存百分比。
EffectivePrivateBytesLimit获取可用于缓存的字节数。
Item获取或设置指定键处的缓存项。

二、方法

方法名称说明
Add将指定项添加到 Cache 对象,该对象具有依赖项、到期和优先级策略以及一个委托(可用于在从 Cache 移除插入项时通知应用程序)。
Get从 Cache 对象检索指定项。
GetEnumerator检索用于循环访问包含在缓存中的键设置及其值的字典枚举数。
Insert(String, Object)向 Cache 对象插入项,该项带有一个缓存键引用其位置,并使用 CacheItemPriority 枚举提供的默认值。
Insert(String, Object, CacheDependency)向 Cache 中插入具有文件依赖项或键依赖项的对象。
Insert(String, Object, CacheDependency, DateTime, TimeSpan)向 Cache 中插入具有依赖项和到期策略的对象。
Insert(String, Object, CacheDependency, DateTime, TimeSpan, CacheItemUpdateCallback)将对象与依赖项、到期策略以及可用于在从缓存中移除项之前通知应用程序的委托一起插入到 Cache 对象中。
Insert(String, Object, CacheDependency, DateTime, TimeSpan, CacheItemPriority, CacheItemRemovedCallback)向 Cache 对象中插入对象,后者具有依赖项、到期和优先级策略以及一个委托(可用于在从 Cache 移除插入项时通知应用程序)。
Remove从应用程序的 Cache 对象移除指定项。

三、静态字段

名称说明
NoAbsoluteExpiration用于 Insert 方法调用中的 absoluteExpiration 参数中以指示项从不到期。 此字段为只读。
NoSlidingExpiration用作 Insert 或 Add 方法调用中的 slidingExpiration 参数,以禁用可调到期。 此字段为只读。

先来看基本的示例:

index.aspx.cs页面代码:

namespace WebApplication1
{public partial class _Default : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){Person p = new Person();p.Id = 1;p.Name = "诸葛亮";Cache cache = HttpRuntime.Cache;cache.Insert("AA",p);cache.Insert("BB","字符串");Response.Write(cache.Get("BB").ToString());     //输出 字符串Person p2 = cache["AA"] as Person;Response.Write(p2.Id + " : " + p2.Name);        //输出 1 : 诸葛亮Response.Write(cache.EffectivePrivateBytesLimit);   //-1 这是一个只读属性,那就没什么好说了,只能输出来看看了,但是-1是什么意思呢?无限吗Response.Write(cache.EffectivePercentagePhysicalMemoryLimit);   //98    开始移除项之前可以使用到98%
Response.Write(cache.Count);        //输出 3Response.Write(cache["BB"]);        //输出 字符串 支持索引器式的读取
cache.Remove("BB");        //从cache中移除一项Response.Write("~~~" + cache["BB"] + "~~~");    //移除了输出 null,但程序不报错foreach (var obj in cache){Response.Write(obj.GetType() + "<br/>");    //输出不知道什么鸟东西
            }
        }}public class Person{public int Id{get;set;}public string Name{get;set;}}
}

四、文件缓存依赖

当被依赖的文件更改时,缓存会立即被清空:

index.aspx.cs代码:

    public partial class _Default : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){Cache cache = HttpContext.Current.Cache;//文件缓存依赖cache.Insert("CC", "依赖项测试", new CacheDependency(@"D:\123.txt"));//这时候在about.aspx页面添加一行代码,当更改一下D:123.txt时,cache["cc"]会立即被清空
        }}

about.aspx.cs代码:

    public partial class About : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){//直接打开本页面,输出缓存依赖项测试//当更改D:\123.txt之后,在刷新,输出空,表明该Cache是依赖于D:\123.txt的Response.Write(HttpContext.Current.Cache["CC"]);}}

五、NoSlidingExpiration 绝对过期时间

  NoSlidingExpiration  绝对过期时间,当超过设定时间,立即移除。

下面来看下绝对过期时间的示例,index.aspx.cs:

    public partial class _Default : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){Cache cache = HttpContext.Current.Cache;//30秒后就到期,立即移除,没商量cache.Insert("DD", "绝对过期测试", null, DateTime.Now.AddSeconds(5), System.Web.Caching.Cache.NoSlidingExpiration);}}

about.aspx.cs:

    public partial class About : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){//先打开index.aspx添加到缓存 然后立即打开本页面,输出 绝对过期测试//持续刷新5秒后,不会再输出  绝对过期测试Response.Write(HttpContext.Current.Cache["DD"]);}}

六、NoAbsoluteExpiration 滑动过期时间

  NoAbsoluteExpiration  当超过设定时间没再使用时,才移除缓存

滑动过期测试,index.aspx.cs:

    public partial class _Default : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){Cache cache = HttpContext.Current.Cache;//弹性过期时间,当缓存没使用10秒就过期cache.Insert("DD", "滑动过期测试", null, System.Web.Caching.Cache.NoAbsoluteExpiration,TimeSpan.FromSeconds(10));}}

about.aspx.cs:

    public partial class About : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){//直接打开本页面,输出弹性过期测试//如果一直不停地刷新,都会继续输出,但是当超过10秒后再刷新,不会再输出   滑动缓存测试Response.Write(HttpContext.Current.Cache["DD"]);}}

注意   当设置绝对到期时间时,请使用 DateTime 结构。当设置弹性过期时间时,请使用 TimeSpan 结构。另外,如果您创建的弹性过期时间小于零或大于一年,则将引发 ArgumentOutOfRangeException 类

七、缓存的优先级设置

CacheItemPriority枚举  设置缓存的优先级

    public partial class _Default : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){Cache cache = HttpContext.Current.Cache;//文件权重级别cache.Add("MyData", "缓存重要级别", null, Cache.NoAbsoluteExpiration, TimeSpan.FromSeconds(30), CacheItemPriority.High, null);}}

该枚举一共有六级:

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

八、当缓存被移除时,通知程序

这时就要用到Add的最后一个参数,委托了:

index.aspx.cs代码如下:

    public partial class _Default : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){Cache cache = HttpRuntime.Cache;//文件权重级别cache.Add("MyData", "缓冲移除通知", null, DateTime.Now.AddSeconds(10) ,Cache.NoSlidingExpiration,CacheItemPriority.Low, Show);}public void Show(string key, object value, CacheItemRemovedReason reason){Cache cache = HttpRuntime.Cache;Cache.Insert("MyData", "缓存被清空啦!缓存被清空啦!缓存被清空啦!缓存被清空啦!缓存被清空啦!缓存被清空啦!缓存被清空啦!");}}

about.aspx.cs代码如下:

    public partial class About : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){Response.Write(HttpRuntime.Cache["MyData"]);}}

此处实现的效果时:第一次打开index.aspx(让程序加入数据到缓存),然后打开about.aspx显示出“缓存移除通知”,10秒后再刷新,显示

“缓存被清空啦!缓存被清空啦!缓存被清空啦!缓存被清空啦!缓存被清空啦!缓存被清空啦!缓存被清空啦!”  经测试,以上程序的Cache最好还是用HttpRuntime的,否则没有请求时HttpContext会报,“未将对象引用设置到对象的实例”。

这就是被清空时会自动调用委托程序进行处理,你可以再次将数据添加进入缓存,或者记录到日志等等一系列操作。

九、数据库依赖缓存

  1、配置的方式(sqlserver2000) SqlDependency第一个构造函数。

首先一个WebForm的Web.Config中的配置文件修改如下:

  <connectionStrings><add name="ApplicationServices"connectionString="Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;"providerName="System.Data.SqlClient" /></connectionStrings><system.web>
    <compilation debug="true" targetFramework="4.0" /><caching><sqlCacheDependency enabled="true" pollTime="1000">  //此行配置的意思是,开启数据库缓存,轮询时间为1秒,这是为了能够快速看到更改效果<databases><add connectionStringName="ApplicationServices" name="con"/></databases></sqlCacheDependency></caching></system.web>

修改Global.asax.cs文件代码如下:

        void Application_Start(object sender, EventArgs e){string connString = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString;SqlCacheDependencyAdmin.EnableNotifications(connectionString);     //启动数据库的数据缓存依赖功能                      
       SqlCacheDependencyAdmin.EnableTableForNotifications(connectionString, table);
//启用数据表缓存 }

Index.aspx.cs文件代码如下:

        protected void Page_Load(object sender, EventArgs e){SqlCacheDependency dependency = new SqlCacheDependency("con", "Record");// 新增或修改一条缓存记录HttpRuntime.Cache.Insert("MyData", "数据库缓存测试", dependency);}

About.aspx.cs文件代码如下:

        protected void Page_Load(object sender, EventArgs e){Response.Write(HttpRuntime.Cache["MyData"]);}

次数实现的效果时,打开Index.aspx.cs文件将数据添加到缓存后,然后打开about.asox,页面输出"数据库缓存测试",这时候更改一下数据库的Record表,再刷新about.aspx页面,上一次输出的内容没有了。

System.Data.SqlClient.SqlDependency.Start(connString);
System.Data.SqlClient.SqlDependency.Stop(connString);

这两行代码不一定要放在Global.asax.cs里面,在代码执行之前和执行之后就OK了。

注意,在这个例子当中,数据库要开启Service Broker

  检测是否已经启用Service Broker
Select DATABASEpRoPERTYEX('数据库名称','IsBrokerEnabled')          -- 1 表示已经启用 0 表示没有启用
  启用Servicce Broker
ALTER DATABASE NX SET ENABLE_BROKER;
如果启动时,一直显示正在执行查询,那么用一下这条语句
ALTER DATABASE NX SET NEW_BROKER WITH ROLLBACK IMMEDIATE;
ALTER DATABASE NX SET ENABLE_BROKER;

  2、编程的方式(sqlserver2008),第二个构造函数SqlDependency(sqlcommand sqlcom)

  index.aspx.cs文件代码如下:

        protected void Page_Load(object sender, EventArgs e){SqlCacheDependency dependency;SqlConnection conn = new SqlConnection(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");using (conn){string sql = "select name from dbo.record";SqlCommand cmd = new SqlCommand(sql, conn);dependency = new SqlCacheDependency(cmd);SqlDataAdapter adapter = new SqlDataAdapter(cmd);   //这里要特别注意,你的cmd一定要执行过,或者说Execute过,真正从数据库里面取出过数据DataSet ds = new DataSet();adapter.Fill(ds);   //这里才是cmd真正执行的地方,注意真正执行要在绑定dependency之后}Response.Write("开始!");Cache.Insert("MyData", "数据库依赖测试", dependency);Response.Write("完成!");}

about.aspx.cs代码文件如下:

    public partial class About : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){if (HttpRuntime.Cache["MyData"] != null){Response.Write(HttpRuntime.Cache["MyData"]);}else{Response.Write("缓存已不存在!");}}}

实现的效果一样是,打开index.aspx文件,再打开about.aspx文件,页面输出"缓存测试结果",当更改表record之后,再刷新about.aspx页面,缓存被清空。

再来一个例子,上次又是页面啥的,这次用十几行代码说明,这个东东实现的要点:

        static void Main(string[] args){Cache cache = HttpRuntime.Cache;System.Data.SqlClient.SqlDependency.Start(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");// 创建缓存依赖  SqlConnection conn = new SqlConnection(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");SqlCommand command = new SqlCommand("select Id,name from dbo.Record", conn);SqlCacheDependency dependency = new SqlCacheDependency(command);    //注意,创建的command与SqlCacheDependency绑定要在command执行之前SqlDataAdapter adapter = new SqlDataAdapter(command);   DataSet ds = new DataSet();adapter.Fill(ds);    //这里要特别注意,Fill才是真正执行
            cache.Insert("DD", "数据库依赖测试", dependency);Console.WriteLine(cache["DD"]);Thread.Sleep(20000);     //暂停20秒给你更改一下数据库if (cache["DD"] == null){Console.WriteLine("数据库已经修改过了!");               }Console.ReadKey();System.Data.SqlClient.SqlDependency.Stop(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");}

在途中,我会随便修改一下Record表,输出结果如下:

再来一次数据库缓存依赖,回调函数的例子:

    public class Program{static void Main(string[] args){Cache cache = HttpRuntime.Cache;System.Data.SqlClient.SqlDependency.Start(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");// 创建缓存依赖  SqlConnection conn = new SqlConnection(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");SqlCommand command = new SqlCommand("select Id,name from dbo.Record", conn);SqlCacheDependency dependency = new SqlCacheDependency(command);    //注意,创建的command与SqlCacheDependency绑定要在command执行之前SqlDataAdapter adapter = new SqlDataAdapter(command);   DataSet ds = new DataSet();adapter.Fill(ds);    //这里要特别注意,Fill才是真正执行
CacheItemRemovedCallback callback = new CacheItemRemovedCallback(RemovedCallback);cache.Insert("DD", "数据库依赖测试", dependency, DateTime.Now.AddDays(1), TimeSpan.Zero, CacheItemPriority.Default, callback);Console.WriteLine(cache["DD"]);Thread.Sleep(15000);     //暂停15秒给你更改一下数据库if (cache["DD"] == null){Console.WriteLine("数据库已经修改过了!");               }Console.ReadKey();System.Data.SqlClient.SqlDependency.Stop(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");}public static void RemovedCallback(string key, object value, CacheItemRemovedReason reason){Console.WriteLine("缓存被移除!");Console.WriteLine(reason.ToString());}}

输出结果如下:

这里要补充几点:当设置为绝对过期时,后面那个TimeSpan参数要设为TimeSpan.Zero。另外,重载中还有一个方法之前在缓存移除前执行回调函数的,而刚刚那个是缓存数据被移除之后执行的。

  CacheItemUpdateCallback  缓存数据移除之前调用;

    CacheItemRemoceCallback  缓存数据移除之后调用;

  再来写一个:

    public class Program{static void Main(string[] args){Cache cache = HttpRuntime.Cache;System.Data.SqlClient.SqlDependency.Start(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");// 创建缓存依赖  SqlConnection conn = new SqlConnection(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");SqlCommand command = new SqlCommand("select Id,name from dbo.Record", conn);SqlCacheDependency dependency = new SqlCacheDependency(command);    //注意,创建的command与SqlCacheDependency绑定要在command执行之前SqlDataAdapter adapter = new SqlDataAdapter(command);   DataSet ds = new DataSet();adapter.Fill(ds);    //这里要特别注意,Fill才是真正执行
CacheItemUpdateCallback callback = new CacheItemUpdateCallback(RemovedCallback);cache.Insert("DD", "数据库依赖测试", dependency, DateTime.Now.AddDays(1), TimeSpan.Zero, callback);Console.WriteLine(cache["DD"]);Thread.Sleep(15000);     //暂停15秒给你更改一下数据库if (cache["DD"] == null){Console.WriteLine("数据库已经修改过了!");               }Console.ReadKey();System.Data.SqlClient.SqlDependency.Stop(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");}public static void RemovedCallback(string key, CacheItemUpdateReason reason, out object expensiveObject, out CacheDependency dependency, out DateTime absoluteExpiration, out TimeSpan slidingExpiration){//   key:要从缓存中移除的项的标识符。//   reason:要从缓存中移除项的原因。//   expensiveObject:此方法返回时,包含含有更新的缓存项对象。//   dependency:此方法返回时,包含定义项对象和文件、缓存键、文件或缓存键的数组或另一个 System.Web.Caching.CacheDependency 对象之间的依赖项的对象。//   absoluteExpiration:此方法返回时,包含对象的到期时间。//   slidingExpiration:此方法返回时,包含对象的上次访问时间和对象的到期时间之间的时间间隔。expensiveObject = null;dependency = null;absoluteExpiration = DateTime.Now;slidingExpiration = TimeSpan.Zero;Console.WriteLine("缓存马上被移除!");//但是现在还有没有呢?输出试试Console.WriteLine(HttpRuntime.Cache["DD"]);Console.WriteLine(reason.ToString());}}

输出结果为:

看到,在Update这个委托执行时,缓存还是存在的。

注意:那个SQL语句还是比较严格的,主要要符合以下要求

       a).     必须设置完全限定名称的数据表。即表名前面需要加所有者,如dbo.test。

       b).     必须明确设置所访问数据库列名称,不能使用“*”。

       c).     必须保证不是聚合函数。如COUNT、MAX等。

SQL SERVER 7.0/2000SQL SERVER 2005
实现机制轮询通知传递服务(Service Broker)

是否需要配置启用

需要

不需要,内置支持

数据更改检测

限于表级更改监测

表级、行级更改监测

很明显,SQL SERVER 2005的缓存机制更加高效。另外,SqlCacheDependency类还特别结合SQL SERVER 2005 进行了优化:

a).     使用SQL SERVER 2005 时,SqlCacheDependency类支持与System.Data.SqlClient.SqlDependency类进行集成。应用程序可创建SqlDependency对象,并通过OnChanged事件处理程序接受通知进行注册。这样,应用程序不仅可以使用Sql server 2005的查询通知机制来监测使用SQL查询结果无效的数据更改,并将缓存对象从缓存中移除,而且还可以轻松获取数据更改通知,以便刷新缓存。(从这里可以看出,当触发onRemoveCallback委托的时候,数据已经从缓存里面删除了,这样一来可以手动在委托里面添加缓存,或者干脆设置成null,让他下次调用的时候再缓存。)

b).     不仅向应用程序添加缓存依赖项,还可以与@OutputCache指令一起使用,以生成依赖于SqlServer数据库表的输出缓存的页面或用户控件。对于用户控件,@OutputCache指令不支持使用SQL SERVER 2005 的查询通知(即onRemoveCallback委托)。

十、组合依赖缓存

当依赖的内容为多个Dependency时,可以通过AggregateCacheDependency创建依赖的组合,以便在任何一个依赖项发生变化时,使缓存项失效。
  组合的缓存依赖内部为一个集合,可以保存多个缓存依赖对象,将这些缓存依赖对象作为一个整体应用在缓存项目上,当其中某一个缓存依赖失效的时候,就可以使缓存的数据被丢弃。

组合依赖缓存示例:

//创建缓存依赖
System.Web.Caching.SqlCacheDependency product = new System.Web.Caching.SqlCacheDependency("northwindcache","products");
System.Web.Caching.SqlCacheDependency category = new System.Web.Caching.SqlCacheDependency("northwindcache","products")
//多个缓存依赖组合成一个依赖对象使用
System.Web.Caching.AggregateCacheDependency acd = new System.Web.Caching.AggregateCacheDependency();
acd.Add(product,category);

十一、System.Web.Caching.Cache Insert和Add方法的区别

   Add方法

object Add(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback);

Insert方法

void Insert(string key, object value); //永不过期
void Insert(string key, object value, CacheDependency dependencies);  //依赖
void Insert(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration);//绝对时间过期:
void Insert(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemUpdateCallback onUpdateCallback);  //依赖+回调
void Insert(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback);  //依赖+优先级+回调

   比较、区别

a). Insert方法支持5种重载,使用灵活,而Add方法必须提供7个参数;

b). Add方法可以返回缓存项的数据对象,Insert 返回Void;

c). 添加重复缓存情况下(Key已存在),Insert会替换该项,而Add方法则不执行任何操作,并返回原来保存的object对象(Update 2014-03-18)。

  过期策略

a). 永不过期
      Insert(string key, object value);

b). 绝对时间过期

DateTime.Now.AddSeconds(10)表示缓存在10秒后过期,TimeSpan.Zero表示不使用平滑过期策略。

例:Cache.Insert("Data", ds,null, DateTime.Now.AddSeconds(10), TimeSpan.Zero);

c). 变化时间过期(平滑过期)

DateTime.MaxValue表示不使用绝对时间过期策略,TimeSpan.FromSeconds(10)表示缓存连续10秒没有访问就过期。

例:Cache.Insert("Data", ds, null, DateTime.MaxValue, TimeSpan.FromSeconds(10));

十二、清空缓存

清空缓存主要通过Remove()方法,但是只能通过传入一个Key,清空一个。

GetEnumerator()方法用于获取所有缓存项。MoveNext()用于将位置移动到下一个缓存项。

如果想清空所有缓存,由于Cache类没有提供RemoveAll()方法,所以可以通过以下方式实现:

        IDictionaryEnumerator DicCache = HttpRuntime.Cache.GetEnumerator();int count = HttpRuntime.Cache.Count;for (int i = 0; i < count; i++){DicCache.MoveNext();HttpRuntime.Cache.Remove(DicCache.Entry.Key.ToString());}

十三、缓存依赖总结

缓存依赖主要有如下技术点

Dependency依赖:.Net中支持两种依赖:CacheDependency和SqlDependency(两者都是Dependency的子类)。从.Net2.0开始,CacheDependency不再是密封的,而是可以继承的。
        ┠CacheDependency:表示对文件或者目录的依赖
        ┠SqlDependency:表示基于SQL数据库的依赖

过期时间:过期时间分绝对过期时间和滑动过期时间两种。
     ┠绝对过期时间:为特定时间点,类型为DateTime,如果不使用绝对过期时间,那么,使用System.Web.Caching.Cache.NoAbsoluteExpiration表示。
     ┠滑动过期时间:为一个事件间隔,类型为TimeSpan,如果不使用滑动过期时间,使用System.Web.Cacheing.NoSlidingExpiration表示。

删除通知:.Net提供了一个机制,当被缓存的数据从内存中移除的时候,可以提供一个通知机制,来回调用户定义的方法,方法必须符合CacheItemRemoveCallback委托的定义。该委托定义如下:

public delegate void CacheItemRemoveCallback(string key,Object value,CacheItemRemovedReason reason)

其中,CacheItemRemoveReason为缓存项被移除的原因。CacheItemRemovedReason是一个枚举类型,定义了如下原因:

  1. DependencyChange:由于依赖发生变化被移除;
  2. Expired:由于过期被移除;
  3. Removed:由于调用Insert插入一个同名的缓存项或者调用Remove失效被移除;
  4. Underused:系统移除;

注意:

  • 回调的时机是不可预知的,不能假定回调发生时,回调方法的执行线程存在HttpContext的上下文,为了在没有请求上下文的时候取得对Cache对象的引用,可以通过HttpRuntime的Cache属性来使用应用程序的Cache。
  • 不能在页面上使用实例方法来作为回调方法,当在页面上使用回调方法时,由于指向回调方法的引用会阻止垃圾回收机制,因此会造成内存很快耗光。
  • 一般通过在自定义类的静态方法实现回调方法,或者使用页面对象的静态方法的实现。

PS:

1、 CacheDependency是AggregateCacheDependency和SqlCacheDependency的父类。主要用于在应用程序数据缓存对象与文件、缓存键、文件或缓存键的数组或另外一个CacheDependency对象之间建立依赖关系。CacheDependency监视依赖关系比便在任何对象更改时自动移除缓存对象。CacheDependency可以监测一组(到文件或目录的)文件路径的更改情况。

2、 AggregateCacheDependency主要用于实现聚合缓存依赖。如一笔数据同时对两个表进行缓存依赖,一旦其中任何一个表数据更改缓存将失效。

3、 SqlCacheDependency将应用程序数据缓存对象、页面输出缓存、数据源控件等与指定SQL Server数据库表或Sql Server 2005 查询结果之间建立缓存依赖关系,在表发生更改(Sql Server 2005 行级别更改)时,自动从缓存中删除和重新添加与该表关联的缓存对象。一般而言:

  • SqlCacheDependency (SqlCommand) 用于SQL SERVER 2005
  • SqlCacheDependency (数据库名, 表名) 用于SQL SERVER 7.0/2000

有以下几条缓存数据的规则。:
  第一,数据可能会被频繁的被使用,这种数据可以缓存。 
  第二,数据的访问频率非常高,或者一个数据的访问频率不高,但是它的生存周期很长(很少变动),这样的数据最好也缓存起来。 
  第三,是一个常常被忽略的问题,有时候我们缓存了太多数据,通常在一台X86的机子上,如果你要缓存的数据超过800M的话,就会出现内存溢出的错误。所以说缓存是有限的。换名话说,你应该估计缓存集的大小,把缓存集的大小限制在10以内,否则它可能会出问题。在Asp.net中,如果缓存过大的话也会报内存溢出错误,特别是如果缓存大的DataSet对象的时候。

你应该认真分析你的程序。根据实际情况来看哪里该用,哪里不该用。如:Cache用得过多也会增大服务器的压力。整页输出缓存,又会影响数据的更新。 如果真的需要缓存很大量的数据,可以考虑静态技术。

CacheDependency还支持【嵌套】,即:CacheDependency的构造函数中支持传入其它的CacheDependency实例,这样可以构成一种非常复杂的树状依赖关系。

相关文章:

Python 可视化近 90 天的百度搜索指数 + 词云图

作者 | 叶庭云来源 | AI庭云君一、简介 在实际业务中我们可能会使用爬虫根据关键词获取百度搜索指数历史数据&#xff0c;然后进行对应的数据分析。百度指数&#xff0c;体验大数据之美。但要获取百度指数相关的数据&#xff0c;困难如下&#xff1a;不是静态网页&#xff0c;并…

php常用比较函数区别表

php常用比较函数区别表 表达式 empty() is_null() isset() if($x) $x "" TRUE FALSE TRUE FALSE $x null TRUE TRUE FALSE FALSE $x is undefined TRUE TRUE FALSE FALSE(报E_NOTICE错) $x array() TRUE FALSE TRUE FALSE $x false TRUE FALSE TRUE FALSE $x 0 …

实战分享:淘宝Web 3D应用与游戏开发

大家下午好&#xff01;我们今天讲个比较有意思的话题&#xff0c;这个话题在业界被谈及得比较少。大家在座有做过移动端开发的同学吗&#xff1f;请举个手&#xff0c;人还挺多的。那做过3D应用的同学请举个手&#xff0c;有用过Threejs的请举个手&#xff0c;做过游戏的呢..人…

常见NoSQL系统使用场景分析

•Cassandra •特性&#xff1a;分布式与复制的权衡\根据列和键范围进行查询\BigTable类似的功能&#xff1a;列&#xff0c;列族\写比读快很多 •最佳适用&#xff1a;写操作较多&#xff0c;读比较少的时候。如果你的系统都是基于Java的时候。 •应用场景&#xff1a;银行&am…

再一次输给了AI,弯道急速超车、登上 Nature 封面

作者 | 学术头条来源 | 学术头条人工智能&#xff08;AI&#xff09;的很多潜在应用&#xff0c;涉及与人类交互时做出更优化的实时决策&#xff0c;而竞技或者博弈类游戏&#xff0c;便是最佳的展示舞台。近日&#xff0c;发表在《自然》杂志上的封面文章报告称&#xff0c;AI…

maven 多环境打包

2019独角兽企业重金招聘Python工程师标准>>> 1.在项目的pom中添加 <build><resources><!-- Resource Filter --><resource><directory>src/main/resources</directory><filtering>true</filtering></resource&g…

Sass函数:Sass Maps的函数-map-has-key($map,$key)

map-has-key($map,$key) 函数将返回一个布尔值。当 $map 中有这个 $key&#xff0c;则函数返回 true&#xff0c;否则返回 false。 前面的示例&#xff0c;当 $key 不在 $map 中时&#xff0c;使用 map-get($map,$key) 函数将返回一个 null 值。但对于开发人员&#xff0c;并看…

Memcache内存分配策略

转自&#xff1a;http://tank.blogs.tkiicpp.com/2010/12/14/memcache%e5%86%85%e5%ad%98%e5%88%86%e9%85%8d%e7%ad%96%e7%95%a5/ 一、Memcache内存分配机制关于这个机制网上有很多解释的&#xff0c;我个人的总结如下。 Page为内存分配的最小单位。 Memcached的内存分配以page…

论排列组合,持续更新

今天刚好碰到了一个排列组合问题&#xff0c;因为之前对这方面的学习比较少&#xff0c;所以用的非常蠢的方法做了四位数中取三位的排列&#xff0c;写的程序太有局限性&#xff0c;源码如下#define _CRT_SECURE_NO_WORNINGS 1#include<stdio.h>#include<stdlib.h>…

Python 中少为人知的 10 个安全陷阱

作者&#xff1a;Dennis Brinkrolf译者&#xff1a;豌豆花下猫Python猫原题&#xff1a;10 Unknown Security Pitfalls for Python英文&#xff1a;https://blog.sonarsource.com/10-unknown-security-pitfalls-for-pythonPython 开发者们在使用标准库和通用框架时&#xff0c;…

JS+CSS3 360度全景图插件 - Watch3D.js

日常闲扯 从上一篇文章到这篇中间快过了一年了&#xff0c;时间真滴过得快。不是在下中间没想过写新的文章&#xff0c;而是自己确实变懒了(体重1 1 1 1....) 。。OTL。。。不过到最后觉得还是需要写点东西&#xff0c;不然人就真废了&#xff0c;于是便有了这样一个插件&#…

CQRS学习——最小单元的Cqrs(CommandEvent)[其一]

【说明&#xff1a;博主采用边写边思考的方式完成这一系列的博客&#xff0c;所以代码以附件为准&#xff0c;文中代码仅为了说明。】 结构 在学习和实现CQRS的过程中&#xff0c;首要参考的项目是这个【http://www.cnblogs.com/yangecnu/p/Introduction-CQRS.html】。所以Dpfb…

PHP APC安装与使用

最简单的方法&#xff0c;找到php安装目录的pecl 自动安装&#xff1a; # /usr/local/php/bin/pecl install apc 下面按提示一步步完成即可 配置/etc/php.ini 末尾加入extensionapc.so 手动安装&#xff1a; 官网 http://cn2.php.net/manual/zh/book.apc.php 下载http://p…

AIphaCode 并不能取代程序员,而是开发者的工具

编译 | 禾木木 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; DeepMind 是 AI 研究实验室&#xff0c;它引入了一种深度学习模型&#xff0c;可以生成具有显著效果的软件源代码。该模型名为 AIphaCode&#xff0c;是基于 Transformers&#xff0c;OpenAI 在其代码生…

源码阅读:SDWebImage(六)——SDWebImageCoderHelper

该文章阅读的SDWebImage的版本为4.3.3。 这个类提供了四个方法&#xff0c;这四个方法可分为两类&#xff0c;一类是动图处理&#xff0c;一类是图像方向处理。 1.私有函数 先来看一下这个类里的两个函数 /**这个函数是计算两个整数a和b的最大公约数*/ static NSUInteger gcd(N…

基于 OpenCV 的网络实时视频流传输

作者 | 努比来源 | 小白学视觉大多数人会选择使用IP摄像机&#xff08;Internet协议摄像机&#xff09;而不是CCTV&#xff08;闭路电视&#xff09;&#xff0c;因为它们具有更高的分辨率并降低了布线成本。在本文中&#xff0c;我们将重点介绍IP摄像机。IP摄像机是一种数字 摄…

【转】让Chrome化身成为摸鱼神器,利用Chorme运行布卡漫画以及其他安卓APK应用教程...

下周就是十一了&#xff0c;无论是学生党还是工作党&#xff0c;大家的大概都会有点心不在焉&#xff0c;为了让大家更好的心不在焉&#xff0c;更好的在十一前最后一周愉快的摸鱼&#xff0c;今天就写一个如何让Chrome&#xff08;google浏览器&#xff09;运行安卓APK应用的教…

PHP安装parsekit扩展查看opcode

也可以通过VLD查看&#xff0c;具体请看本人写的http://blog.csdn.net/21aspnet/article/details/7002644安装parsekit扩展 http://pecl.php.net/package/parsekit 下载最新的 #wget http://pecl.php.net/get/parsekit-1.3.0.tgz 安装过程省略 可以参考 本人写的http://blog.c…

group by 查找订单的最新状态 join

Order&#xff1a;snProcedures&#xff1a;sn,status1、 有订单表和流程表。订单表含有订单的详细信息【假设没有订单状态哈】&#xff0c;每个订单有好多种状态&#xff1a;已付款、处理中、待收货等等。现在的需求可能是查询订单状态是待收货的所有订单的信息。【答】先找到…

Xcache安装与使用

官网&#xff1a;http://xcache.lighttpd.net 最新版本下载地址&#xff1a;http://xcache.lighttpd.net/wiki/Release-1.3.2 安装&#xff1a; # wget http://xcache.lighttpd.net/pub/Releases/1.3.2/xcache-1.3.2.tar.gz # tar zvxf xcache-1.3.2.tar.gz # cd xcache-1.3…

安装mysql_python的适合遇到mysql_config not found解决方案(mac)

为什么80%的码农都做不了架构师&#xff1f;>>> 安装mysql_python的适合遇到mysql_config not found解决方案&#xff08;mac&#xff09; 用pip安装MySQL-python时候遇到报错&#xff1a; ------我是分割线------ Complete output from command python setup.py e…

推荐 6 个好用到爆的 Pycharm 插件

作者 | 小欣来源 | Python爱好者集中营相信对于不少的Python程序员们都是用Pycharm作为开发时候的IDE来使用的&#xff0c;今天小编来分享几个好用到爆的Pycharm插件&#xff0c;在安装上之后&#xff0c;你的编程效率、工作效率都能够得到极大地提升。安装方法插件的安装方法一…

Kibana 用户指南(使用Flight仪表盘探索Kibana)

使用Flight仪表盘探索Kibana 你是Kibana的新手并希望尝试一下&#xff0c;只需单击一下&#xff0c;你就可以安装Flights样本数据并开始与Kibana交互。 Flight数据集包含四家航空公司的数据&#xff0c;你可以从Kibana主页加载数据和预配置的仪表盘。 在主页上&#xff0c;单击…

php扩展xdebug安装以及用kcachegrind系统分析

一&#xff1a;安装 安装方法一&#xff1a;编译安装1、下载PHP的XDebug扩展&#xff0c;网址&#xff1a;http://xdebug.org/# wget http://pecl.php.net/get/xdebug-2.1.2.tgz# tar -xzf xdebug-2.1.2.tgz# xdebug-2.1.2# cd xdebug-2.1.2# /usr/local/php/bin/phpize# ./con…

Meta AI 新研究,统一模态的自监督新里程碑

作者 | 青苹果来源 | 数据实战派虽然 AI 领域不断涌现出新的突破和进展&#xff0c;却始终难以逃离单一领域的束缚——一种用于个性化语音合成的新颖方法&#xff0c;却并不能用于识别人脸的表情。为了解决这个问题&#xff0c;不少研究人员正在致力于开发功能更强大、应用更广…

细说Debug和Release区别

VC下Debug和Release区别 最近写代码过程中&#xff0c;发现 Debug 下运行正常&#xff0c;Release 下就会出现问题&#xff0c;百思不得其解&#xff0c;而Release 下又无法进行调试&#xff0c;于是只能采用printf方式逐步定位到问题所在处&#xff0c;才发现原来是给定的一个…

26期20180601目录管理

6月1日任务2.1/2.2 系统目录结构2.3 ls命令2.4 文件类型2.5 alias命令系统目录结构ls - list所有的用户在系统里都有自己的家目录&#xff0c;比如现在登陆的是root用户&#xff0c;登陆进去就是在root的家目录中&#xff0c;可以看到之前创建的公钥文件也是在这。但是如果是其…

thttpd安装与调试

http://www.acme.com/software/thttpd/ thttpd是一个非常小巧的轻量级web server&#xff0c;它非常非常简单&#xff0c;仅仅提供了HTTP/1.1和简单的CGI支持&#xff0c;在其官方网站上有一个与其他web server&#xff08;如Apache, Zeus等&#xff09;的对比图Benchmark&…

7 款可替代 top 命令的工具!(二)

作者 | JackTian来源 | 杰哥的IT之旅上一篇文章中给大家介绍了《11 款可替代 top 命令的工具&#xff01;》&#xff0c;今天我再来给大家推荐 7 款可替代 top 命令的工具&#xff0c;看完这两篇替代品的文章相信能让你对 Linux 操作系统下一个小小的命令大开眼界。一、atopato…

Error:Execution failed for task ':app:dexDebug'. com.android.ide.common.process.ProcessException

异常Log&#xff1a; Error:Execution failed for task ‘:app:dexDebug’. > com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process ‘command ‘/Library/……/java” finished with non-zero exit value 2 错误原因&am…