什么是缓存?缓存技术是将经常使用的数据/信息存储在内存中的技术,以便下次需要相同的数据/信息时,可以直接从内存中检索,而不是由应用程序生成。
缓存对于提高asp.net性能非常重要,因为页面和控件是在这里动态生成的。这对于数据相关的事务尤其重要,因为这些事务在响应时间上是昂贵的。
高速缓存将常用数据放置在快速访问的媒体中,例如计算机的随机存取存储器。 asp.net运行时包含称为缓存的clr对象的键值映射。 这驻留在应用程序中,可通过httpcontext
和system.web.ui.page
获取。
在某些方面,缓存类似于存储状态对象。 然而,在状态对象中存储信息是确定性的,即可以指望存储在那里的数据,并且数据的缓存是非确定性的。
在以下情况下数据将不可用:
可以使用索引器访问缓存中的项目,并可以控制缓存中对象的生存期并设置缓存对象与其物理源之间的链接。
asp.net提供了以下不同类型的缓存:
输出缓存 - 输出缓存存储最终呈现的html页面的副本或发送到客户端的部分页面。 当下一个客户请求这个页面时,不用重新生成页面,而是发送页面的缓存副本,从而节省时间。
数据缓存 - 数据缓存意味着缓存来自数据源的数据。只要缓存未过期,就会从缓存中满足对数据的请求。 当缓存过期时,数据源获取新的数据,并重新填充缓存。
对象缓存 - 对象缓存缓存页面上的对象,如数据绑定控件。 缓存的数据存储在服务器内存中。
类缓存 - web页面或web服务在第一次运行时会汇编到程序集中的页面类中。然后程序集被缓存在服务器中。下一次请求页面或服务时,会引用缓存的程序集。 当源代码改变时,clr重新编译程序集。
配置缓存 - 应用程序范围的配置信息存储在配置文件中。 配置缓存将配置信息存储在服务器内存中。
在本教程中,我们将考虑输出缓存,数据缓存和对象缓存。
渲染页面可能涉及一些复杂的过程,如数据库访问,渲染复杂的控件等。输出缓存允许通过缓存内存中的数据绕过服务器往返。即使整个页面也可以被缓存。
outputcache
指令负责输出缓存。它启用输出缓存并提供对其行为的一定控制。
outputcache
指令的语法:
<%@ outputcache duration="15" varybyparam="none" %>
把这个指令放在page
指令下。这告诉环境缓存页面15
秒。 以下用于页面加载的事件处理程序将有助于测试页面是否真正被缓存。
protected void page_load(object sender, eventargs e)
{
thread.sleep(10000);
response.write("this page was generated and cache at:" +
datetime.now.tostring());
}
thread.sleep()
方法在指定的时间内停止进程线程。 在这个例子中,线程停止了10
秒,所以当第一次加载页面时,需要10
秒。 但是,下次刷新页面时,不需要任何时间,因为页面是从缓存中检索的而不是重新加载的。
outputcache
指令具有以下属性,这有助于控制输出缓存的行为:
编号 | 属性 | 值 | 描述 |
---|---|---|---|
1 | diskcacheable |
true/false |
指定可以将输出写入基于磁盘的缓存。 |
2 | nostore |
true/false |
指定是否发送“无存储”缓存控制标题。 |
3 | cacheprofile |
字符串名称 | 要存储在web.config 中的缓存配置文件的名称。 |
4 | varybyparam |
none * param-name |
以分号分隔的字符串列表指定post 请求中或get 请求变量中的查询字符串值。 |
5 | varybyheader |
*header names |
以分号分隔的字符串列表指定可能由客户端提交的标头。 |
6 | varybycustom |
浏览器 自定义字符串 | 告诉asp.net通过浏览器名称和版本或自定义字符串来改变输出缓存。 |
7 | location |
any client downstream server none | any :页面可能被缓存在任何地方。client :缓存的内容保留在浏览器中。downstream :存储在下游和服务器中的缓存内容。server :仅在服务器上保存的缓存内容。 |
8 | duration |
数字 | 页面或控件被缓存的秒数。 |
添加一个文本框和一个按钮到前面的例子,并添加这个按钮的事件处理程序。
protected void btnmagic_click(object sender, eventargs e)
{
response.write("<br><br>");
response.write("<h2> hello, " + this.txtname.text + "</h2>");
}
更改outputcache
指令:
<%@ outputcache duration="60" varybyparam="txtname" %>
程序执行时,asp.net会根据文本框中的名称来缓存页面。
数据缓存的主要方面是缓存数据源控件。 我们已经讨论过,数据源控件代表数据源中的数据,如数据库或xml文件。这些控件派生自抽象类datasourcecontrol
,并具有以下用于实现缓存的继承属性:
为了演示数据缓存,创建一个新的网站并在其上添加一个新的web表单。 使用数据访问教程中已经使用的数据库连接添加一个sqldatasource
控件。
对于这个例子,添加一个标签到页面,这将显示页面的响应时间。
<asp:label id="lbltime" runat="server"></asp:label>
内容页面除了标签之外,与数据访问教程中的内容页面相同。 为页面加载事件添加一个事件处理程序:
protected void page_load(object sender, eventargs e)
{
lbltime.text = string.format("page posted at: {0}", datetime.now.tolongtimestring());
}
设计好的页面应该如下所示:
当您第一次执行页面时,没有什么不同,标签显示,每次刷新页面时,页面都会重新加载,并且标签上显示的时间会发生变化。
接下来,将数据源控件的enablecaching
属性设置为true
,并将cacheduration
属性设置为60
。 它将实现缓存,缓存将每60秒过期。
每次刷新都会更改时间戳,但如果在60秒内更改了表中的数据,则在缓存过期之前不会显示该数据。
参考以下代码 -
<asp:sqldatasource id = "sqldatasource1" runat = "server"
connectionstring = "<%$ connectionstrings: aspdotnetstepbystepconnectionstring %>"
providername = "<%$ connectionstrings: aspdotnetstepbystepconnectionstring.providername %>"
selectcommand = "select * from [dotnetreferences]"
enablecaching = "true" cacheduration = "60">
</asp:sqldatasource>
对象缓存比其他缓存技术提供更多的灵活性。 可以使用对象缓存将任何对象放置在缓存中。 该对象可以是任何类型 - 数据类型,web控件,类,数据集对象等。只需通过分配新的键名称即可将该项添加到缓存中,如下所示:
cache["key"] = item;
asp.net还提供了将对象插入缓存的insert()
方法。 此方法有四个重载版本。如下所列 -
编号 | 方法 | 描述 |
---|---|---|
1 | cache.insert((key, value); |
使用键名称和值将项目插入高速缓存,默认优先级和到期。 |
2 | cache.insert(key, value, dependencies); |
将项目插入高速缓存中,其中包含键值,默认优先级,到期时间以及链接到其他文件或项目的cachedependency 名称,以便在更改缓存项目时不再有效。 |
3 | cache.insert(key, value, dependencies, absoluteexpiration, slidingexpiration); |
这表明与上述问题一起的到期策略。 |
4 | cache.insert(key, value, dependencies, absoluteexpiration, slidingexpiration, priority, onremovecallback); |
这个参数和参数也允许设置缓存项目的优先级和一个委托,指向一个方法被调用时,该项目被删除。 |
滑动到期用于在指定的时间间隔内未使用时从缓存中删除项目。 以下代码片段存储滑动过期时间为10
分钟,不具有依赖性。
cache.insert("my_item", obj, null, datetime.maxvalue, timespan.fromminutes(10));
用一个按钮和一个标签创建一个页面。 在页面加载事件中写入以下代码:
protected void page_load(object sender, eventargs e)
{
if (this.ispostback)
{
lblinfo.text += "page posted back.<br/>";
}
else
{
lblinfo.text += "page created.<br/>";
}
if (cache["testitem"] == null)
{
lblinfo.text += "creating test item.<br/>";
datetime testitem = datetime.now;
lblinfo.text += "storing test item in cache ";
lblinfo.text += "for 30 seconds.<br/>";
cache.insert("testitem", testitem, null,
datetime.now.addseconds(30), timespan.zero);
}
else
{
lblinfo.text += "retrieving test item.<br/>";
datetime testitem = (datetime)cache["testitem"];
lblinfo.text += "test item is: " + testitem.tostring();
lblinfo.text += "<br/>";
}
lblinfo.text += "<br/>";
}
当页面第一次被加载时,输出为:
page created.
creating test item.
storing test item in cache for 30 seconds.
如果您在30
秒内再次单击该按钮,页面将被回发,但标签控件从缓存中获取其信息,如下所示:
page posted back.
retrieving test item.
test item is: 14-07-2017 22:25:34