ASP.NET与ASP.NET MVC 中Cache的总结
2014-08-19 09:41
85 查看
Cache有多种翻译,可以是高速缓冲存储器,也可以是法国的服装品牌,本文只是简单的谈谈就是ASP.NET 中Cache,做过Web应用程序的都知道,如果网站访问量比较大,系统应用程序可以将那些频繁访问的数据,以及那些需要大量处理时间来创建的数据存储在内存中,从而提高性能。 举一个很简单的例子,如果在博客园发布文章到首页,发布之后是不能即时看到自己的文章的,大概一分钟之后才能刷出数据,这就是常用的页面缓存.缓存分为两种,一般都是页面缓存以及应用程序缓存。
首先看一个常用的,用来控制页面或者用户控制输出的持续输出30s时间,WebForm只需要在aspx页面写个OutPutCache:
asp.net mvc页面生命周期跟WebForm那一套不一样,这个时候就需要在Action动手改改:
页面缓存的实现和处理方式有很多种,先从OutPutCache中的各种特性的,每种特性,对应着不同的实现方式:
OutPutCache上面的设置很简单,Duration是必填的,页或用户控件进行缓存的时间(秒),Location是指定缓存的位置,由枚举OutputCacheLocation来确定,包含在用户控件(.ascx 文件)中的 @ OutputCache 指令不支持此特性。
VaryByControl一个分号分隔的字符串列表,用于更改用户控件的输出缓存。 这些字符串代表用户控件中声明的 ASP.NET 服务器控件的 ID 属性值,在 ASP.NET 页和用户控件上使用 @ OutputCache 指令时,需要此特性或 VaryByParam 特性,有的时候我们缓存整个页面肯定不是太现实的,很多情况下只是缓存一部分页面,新建一个用户控件:
在aspx页面中使用用户控件:
这里面涉及到一个问题,就是页面设置的时间和控件设置的时间,页面是10s,控件是5s,控件与页面都是10s刷一次,以页面时间为主;如果页面是10s,控件是20s,那么页面10s刷一次,控件20s刷一次,简单点理解就是控件以时间长的为主;
asp.net mvc 中ascx所有的功能就是View页面,跟局部视图调用一样,新建一个Test.ascx,通过控制器去访问:
注意:控制器多加了Response.Cache.SetOmitVaryStar(true),这个Bug还比较隐蔽,详情可参考:
http://www.cnblogs.com/dudu/archive/2012/08/27/asp_net_mvc_outputcache.html
VaryByCustom表示自定义输出缓存要求的任意文本。 如果特性的赋值为 browser,缓存将随浏览器名称和主要版本信息的不同而异。 如果输入自定义字符串,则必须在应用程序的 Global.asax 文件中重写 GetVaryByCustomString方法, 根据用户的主机名或者浏览器起版本给出缓存,不存在的话就需要新建缓存,如果存在话就不需要新建缓存。
VaryByHeader
分号分隔的 HTTP 标头列表,用于使输出缓存发生变化。 将该特性设为多标头时,对于每个指定标头组合,输出缓存都包含一个不同版本的请求文档。设置 VaryByHeader 特性将启用在所有 HTTP 1.1 版缓存中缓存项,而不仅仅在 ASP.NET 缓存中进行缓存。 用户控件中的 @ OutputCache指令不支持此特性。
VaryByParam
分号分隔的字符串列表,用于使输出缓存发生变化。 默认情况下,这些字符串对应于使用 GET 方法特性发送的查询字符串值,或者使用 POST 方法发送的参数。 将该特性设置为多个参数时,对于每个指定参数组合,输出缓存都包含一个不同版本的请求文档。 可能的值包括 none、星号 (*) 以及任何有效的查询字符串或 POST 参数名称。
页面通过URL链接访问,要缓存页面,百分之九十的情况的下页面是会有参数传递的,如果你设置为none,那么你用get或者post请求的时候是不会缓存的,设为*是最简单的什么都不用管,如果你只想查name的时候缓存一下,那么你直接设置一下就行.
CacheProfile
配置文件中设置缓存。 这是可选特性,默认值为空字符串 ("")。包含在用户控件(.ascx 文件)中的 @ OutputCache 指令不支持此特性。 在页中指定此属性时,属性值必须与 outputCacheSettings 节下面的 outputCacheProfiles 元素中的一个可用项的名称匹配。 如果此名称与配置文件项不匹配,将引发异常。
Shared一个布尔值,确定用户控件输出是否可以由多个页共享。 默认值为 false,包含在 ASP.NET 页(.aspx 文件)中的 @ OutputCache 指令不支持此特性。
NoStore一个布尔值,它决定了是否阻止敏感信息的二级存储。在用户控件(ascx)中使用的时候需要注意加上Response.Cache.SetNoStore();
SqlDependency标识一组数据库/表名称对的字符串值,页或控件的输出缓存依赖于这些名称对。
ProviderName 一个字符串值,标识要使用的自定义输出缓存提供程序。
VaryByContentEncodings 以分号分隔的字符串列表,用于更改输出缓存。
通过键和值直接设置项向缓存赋值
Insert的方式
添加依赖项,可以是其他已存在的缓存,也可以是已存在的文件:
插入多个缓存依赖
绝对过期和滑动过期这个两个名字比较有意,绝对过期枚举英文是NoSlidingExpiration(不滑动),滑动过期NoAbsoluteExpiration(不绝对),这里面还设置了CacheItemPriority,这枚举大家自己看下就行,还有一个自动删除,缓存到期后执行删除方法:
Add的形式(该方法没有重载)
View Code
然后配置文件中进行相应配置:
默认情况下,所有 HTTP 响应、所呈现的页面和控件(其中 defaultProvider 特性设置为 AspNetInternalProvider)所示的内存输出缓存。通过为 defaultProvider 指定不同的提供程序名称,可以更改用于 Web 应用程序的默认输出缓存提供程序。默认值为“AspNetInternalProvider", 这是 ASP.NET 提供的内存缓存。
页面缓存
页面输出缓存是一类针服务器应用程序的典型缓存。 利用输出缓存,可以存储呈现的 HTML。 提供存储的 HTML 以响应相同页的后续请求。 可使用输出缓存来缓存整个网页或仅缓存 ASP.NET 控件的输出。页输出缓存在内存中存储处理后的 ASP.NET 页的内容。 这可让 ASP.NET 向客户端发送页响应,而不必再次经过页处理生命周期。 页输出缓存对于那些不经常更改,但需要大量处理才能创建的页特别有用。 例如,如果创建大通信量的网页来显示不需要频繁更新的数据,页输出缓存则可以极大地提高该页的性能。 可以分别为每个页配置页缓存,也可以在 Web.config 文件中创建缓存配置文件。利用缓存配置文件,只定义一次缓存设置就可以在多个页中使用这些设置。首先看一个常用的,用来控制页面或者用户控制输出的持续输出30s时间,WebForm只需要在aspx页面写个OutPutCache:
<%@ OutputCache Duration="30" VaryByParam="None" %>
asp.net mvc页面生命周期跟WebForm那一套不一样,这个时候就需要在Action动手改改:
[OutputCache(Duration = 30,VaryByParam="none")] public ActionResult CacheTest() { return View(); }
页面缓存的实现和处理方式有很多种,先从OutPutCache中的各种特性的,每种特性,对应着不同的实现方式:
<%@ OutputCache Duration="100"(必填) Location="Any | Client | Downstream | Server | None | ServerAndClient " Shared="True | False" VaryByControl="控件名称" VaryByCustom="Test" VaryByHeader="headers" VaryByParam="parametername" VaryByContentEncoding="encodings" CacheProfile="cache profile name | ''" NoStore="true | false" SqlDependency="database/table name pair | CommandNotification" ProviderName="Provider Name" %>
OutPutCache上面的设置很简单,Duration是必填的,页或用户控件进行缓存的时间(秒),Location是指定缓存的位置,由枚举OutputCacheLocation来确定,包含在用户控件(.ascx 文件)中的 @ OutputCache 指令不支持此特性。
VaryByControl一个分号分隔的字符串列表,用于更改用户控件的输出缓存。 这些字符串代表用户控件中声明的 ASP.NET 服务器控件的 ID 属性值,在 ASP.NET 页和用户控件上使用 @ OutputCache 指令时,需要此特性或 VaryByParam 特性,有的时候我们缓存整个页面肯定不是太现实的,很多情况下只是缓存一部分页面,新建一个用户控件:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Test.ascx.cs" Inherits="MyWebForm.Test" %> <%@ OutputCache Duration="5" VaryByParam="None" %> <% string t = DateTime.Now.ToString(); Response.Write(t); %>
在aspx页面中使用用户控件:
<%@ Register Src="~/Test.ascx" TagPrefix="uc1" TagName="Test" %> <%@ OutputCache Duration="10" VaryByParam="None" %> <uc1:Test runat="server" ID="Test1" />
这里面涉及到一个问题,就是页面设置的时间和控件设置的时间,页面是10s,控件是5s,控件与页面都是10s刷一次,以页面时间为主;如果页面是10s,控件是20s,那么页面10s刷一次,控件20s刷一次,简单点理解就是控件以时间长的为主;
asp.net mvc 中ascx所有的功能就是View页面,跟局部视图调用一样,新建一个Test.ascx,通过控制器去访问:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> <% string t = DateTime.Now.ToString(); Response.Write(t); %>
[OutputCache(Duration=5,VaryByParam="none")] public ActionResult Test() { Response.Cache.SetOmitVaryStar(true); return View(); }
注意:控制器多加了Response.Cache.SetOmitVaryStar(true),这个Bug还比较隐蔽,详情可参考:
http://www.cnblogs.com/dudu/archive/2012/08/27/asp_net_mvc_outputcache.html
VaryByCustom表示自定义输出缓存要求的任意文本。 如果特性的赋值为 browser,缓存将随浏览器名称和主要版本信息的不同而异。 如果输入自定义字符串,则必须在应用程序的 Global.asax 文件中重写 GetVaryByCustomString方法, 根据用户的主机名或者浏览器起版本给出缓存,不存在的话就需要新建缓存,如果存在话就不需要新建缓存。
public override string GetVaryByCustomString(HttpContext context, string arg) { if (arg == "Test") { return "浏览器版本=" + context.Request.Browser.MinorVersion.ToString(); //return "用户主机=" + // context.Request.UserHostName; } return base.GetVaryByCustomString(context, arg); }
VaryByHeader
分号分隔的 HTTP 标头列表,用于使输出缓存发生变化。 将该特性设为多标头时,对于每个指定标头组合,输出缓存都包含一个不同版本的请求文档。设置 VaryByHeader 特性将启用在所有 HTTP 1.1 版缓存中缓存项,而不仅仅在 ASP.NET 缓存中进行缓存。 用户控件中的 @ OutputCache指令不支持此特性。
VaryByParam
分号分隔的字符串列表,用于使输出缓存发生变化。 默认情况下,这些字符串对应于使用 GET 方法特性发送的查询字符串值,或者使用 POST 方法发送的参数。 将该特性设置为多个参数时,对于每个指定参数组合,输出缓存都包含一个不同版本的请求文档。 可能的值包括 none、星号 (*) 以及任何有效的查询字符串或 POST 参数名称。
页面通过URL链接访问,要缓存页面,百分之九十的情况的下页面是会有参数传递的,如果你设置为none,那么你用get或者post请求的时候是不会缓存的,设为*是最简单的什么都不用管,如果你只想查name的时候缓存一下,那么你直接设置一下就行.
[OutputCache(Duration = 30,VaryByParam="name")] public ActionResult CacheTest(string name) { if (name=="1") { ViewData["Test"] = "测试"; } return View(); }
CacheProfile
配置文件中设置缓存。 这是可选特性,默认值为空字符串 ("")。包含在用户控件(.ascx 文件)中的 @ OutputCache 指令不支持此特性。 在页中指定此属性时,属性值必须与 outputCacheSettings 节下面的 outputCacheProfiles 元素中的一个可用项的名称匹配。 如果此名称与配置文件项不匹配,将引发异常。
[OutputCache(CacheProfile = "myProfile",VaryByParam="none")] public ActionResult Test() { Response.Cache.SetOmitVaryStar(true); return View(); }
<system.web> <caching> <outputCacheSettings> <outputCacheProfiles> <add name="myProfile" duration="10"/> </outputCacheProfiles> </outputCacheSettings> </caching> </system.web>
Shared一个布尔值,确定用户控件输出是否可以由多个页共享。 默认值为 false,包含在 ASP.NET 页(.aspx 文件)中的 @ OutputCache 指令不支持此特性。
NoStore一个布尔值,它决定了是否阻止敏感信息的二级存储。在用户控件(ascx)中使用的时候需要注意加上Response.Cache.SetNoStore();
SqlDependency标识一组数据库/表名称对的字符串值,页或控件的输出缓存依赖于这些名称对。
ProviderName 一个字符串值,标识要使用的自定义输出缓存提供程序。
VaryByContentEncodings 以分号分隔的字符串列表,用于更改输出缓存。
应用程序缓存
应用程序缓存提供了一种编程方式,可通过键/值对将任意数据存储在内存中。 使用应用程序缓存与使用应用程序状态类似。 但是,与应用程序状态不同的是,应用程序缓存中的数据是易失的, 即数据并不是在整个应用程序生命周期中都存储在内存中。 使用应用程序缓存的优点是由 ASP.NET 管理缓存,它会在项过期、无效、或内存不足时移除缓存中的项。 还可以配置应用程序缓存,以便在移除项时通知应用程序。使用应用程序缓存的模式是,确定在访问某一项时该项是否存在于缓存中,如果存在,则使用。 如果该项不存在,则可以重新创建该项,然后将其放回缓存中。 这一模式可确保缓存中始终有最新的数据。通过键和值直接设置项向缓存赋值
List<Person> list = new List<Person>(){new Person(){Name="Small",Age=24}, new Person(){Name="Fly",Age=24}, new Person(){Name="Elephant",Age=24}}; Cache["Test"] = list;
Insert的方式
Cache.Insert("Fly", "缓存2");
添加依赖项,可以是其他已存在的缓存,也可以是已存在的文件:
Cache.Insert("Fly", "缓存2");
Cache.Insert("Elephant", "缓存3",new CacheDependency(null, new string[]{"Fly"}));//key为Elephant, value为缓存3,依赖于key为Fly的缓存
Cache.Insert("Elephant", "缓存3",new CacheDependency(Server.MapPath("路径")));
插入多个缓存依赖
CacheDependency dep1 = new CacheDependency(null, new string[] { "Fly" }); CacheDependency dep2 = new CacheDependency(Server.MapPath("路径")); AggregateCacheDependency cacheList = new AggregateCacheDependency(); cacheList.Add(dep1); cacheList.Add(dep2); Cache.Insert("Elephant", "缓存3",cacheList);
绝对过期和滑动过期这个两个名字比较有意,绝对过期枚举英文是NoSlidingExpiration(不滑动),滑动过期NoAbsoluteExpiration(不绝对),这里面还设置了CacheItemPriority,这枚举大家自己看下就行,还有一个自动删除,缓存到期后执行删除方法:
//绝对过期时间的时间为30s,过完30s之后就没有缓存 Cache.Insert("Tiger", "老虎",null, DateTime.Now.AddSeconds(30), Cache.NoSlidingExpiration,CacheItemPriority.High,Show); //滑动过期时间的时间为1分钟,只要一直刷新一直有,如果刷新间隔超过一分钟的缓存就没啦 Cache.Insert("Dragon", "龙", null, Cache.NoAbsoluteExpiration,new TimeSpan(0, 0, 60)); public void Show(string key, object value, CacheItemRemovedReason call) { if (key=="Pig") { Cache.Remove("Pig"); } }
Add的形式(该方法没有重载)
Cache.Add("Cow", "牛", null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
可扩展性缓存
ASP.NET 1到3.5中的输出缓存有一个限制,就是缓存存储本身不是可扩展的,ASP.NET 4.0之后是支持缓存扩展的。 通过缓存的扩展,可以保存HTML页面或者内存中的数据, 这些存储选项包括本地或远程磁盘、云存储和分布式缓存引擎。ASP.NET 中的输出缓存提供程序扩展性,可以为网站设计更好的输出缓存策略。 例如,可以创建这样一个输出缓存提供程序,该程序在内存中缓存站点流量排名靠前的页面,而在磁盘上缓存流量较低的页面,也可以对所呈现页面的各种变化因素组合进行缓存,但应使用分布式缓存以减少前端 Web 服务器的内存消耗。实现可扩展,需要创建一个继承自 OutputCacheProvider 的类:public class MyCacheProvide : OutputCacheProvider { public override object Add(string key, object entry, DateTime utcExpiry) { throw new NotImplementedException(); } public override object Get(string key) { throw new NotImplementedException(); } public override void Remove(string key) { throw new NotImplementedException(); } public override void Set(string key, object entry, DateTime utcExpiry) { throw new NotImplementedException(); } }
View Code
然后配置文件中进行相应配置:
<caching> <outputCache defaultProvider="AspNetInternalProvider"> <providers> <add name="DiskCache" type="MyWeb.Controllers.MyCacheProvide, MyWeb" /> </providers> </outputCache> </caching>
默认情况下,所有 HTTP 响应、所呈现的页面和控件(其中 defaultProvider 特性设置为 AspNetInternalProvider)所示的内存输出缓存。通过为 defaultProvider 指定不同的提供程序名称,可以更改用于 Web 应用程序的默认输出缓存提供程序。默认值为“AspNetInternalProvider", 这是 ASP.NET 提供的内存缓存。
相关文章推荐
- 关于ASP.NET在IIS一些问题的经验总结
- 蛙蛙推荐:蛙蛙学习asp.net总结(之一)
- 项目技术经验总结一:asp.net+oracle部署,防火墙端口开设
- ASP.NET 部署总结 (定时更新)
- Asp.net性能优化总结(一)
- asp.net三种重定向方法的总结
- 代码阅读总结之ASP.NET StartKit TimeTracker(数据绑定之困惑笔记)
- ASP.NET中的FILE对象总结
- 代码阅读总结之ASP.NET StartKit TimeTracker(自定义集合类排序(Sort())方法随笔)
- ASP.NET中的FILESTREAM对象总结
- ASP.net中动态加载控件时一些问题的总结
- VS.NET调试 ASP.NET出现的常见错误总结
- 代码阅读总结之ASP.NET StartKit TimeTracker(QueryString之改进笔记)
- 代码阅读总结之ASP.NET StartKit Commerce
- 关于ASP.NET在IIS一些问题的经验总结
- ASP.NET中的FILE对象总结
- VS.NET调试 ASP.NET出现的常见错误总结
- 代码阅读总结之ASP.NET StartKit TimeTracker(角色权限之捉虫笔记)
- Asp.net小技术总结1
- 代码阅读总结之ASP.NET StartKit TimeTracker(应用程序路径之处理笔记)