您的位置:首页 > 编程语言 > ASP

ASP.NET MVC 教程 -使用输出缓存提高性能(C#)

2012-11-21 11:41 956 查看
ASP.NET MVC 教程 -使用输出缓存提高性能(C#)

原文地址:http://www.asp.net/learn/mvc/tutorial-15-cs.aspx

在这篇教程里,你会学习到利用缓存输出会多么显著地改善你的ASP.NET MVC应用的性能。你会学习到如何缓存从控制器行为返回的结果。通过缓存从控制器行为返回的结果,每次新的用户调用该行为时,相同的内容不再需要每次都创建一次。

使用输出缓存提高性能(C#)
在这篇教程里,你会学习到利用缓存输出会多么显著地改善你的ASP.NET MVC应用的性能。你会学习到如何缓存从控制器行为返回的结果。通过缓存从控制器行为返回的结果,每次新的用户调用该行为时,相同的内容不再需要每次都创建一次。

假设你的ASP.NET MVC应用在一个名叫Index的视图里显示数据库记录的列表。通常情况下,每一次一个用户调用控制器行为就返回Index 视图,而数据库记录集则必须从数据库里通过执行数据库查询来返回检索。

假设,从另外一方面来说,你利用了输出缓存那么你就可以避免任何用户调用同一控制器行为时执行数据库查询。该视图可以从缓存里检索而不是重新从控制器行为里生成。缓存让你避免了服务器端冗余的工作。

启用输出缓存
你可以通过添加一个[OutputCache]属性到一个单独的控制器行为或一整个控制器类。例如,清单1的控制器暴露了一个名叫Index()的行为。Index()行为的输出被缓存10秒。

清单1 - Controllers\HomeController.cs

using System.Web.Mvc;

namespace MvcApplication1.Controllers

{

[HandleError]

public class HomeController : Controller

{

[OutputCache(Duration=10, VaryByParam="none")]

public ActionResult Index()

{

return View();

}

}

}

在ASP.NET MVC的Beta版,输出缓存在这种URL"http://www.MySite.com/"不会正常工作。相反,你必须输入一个像"http://www.MySite.com/Home/Index"这样的URL。

在清单1,Index()行为的输出被缓存了10秒。如果你喜欢,你也指定一个比较长的缓存周期。例如,如果你想要缓存一个控制器行为的输出一天,那么你可以指定缓存周期为86400秒(60秒×60分×24小时)。

没有谁保证内容就会按你指定的时间缓存那么久。当内存资源变低的时候,缓存会自动地驱逐内容。

清单1的Home控制器返回了清单2里的Index视图。这个视图没有什么特别的。Index视图简单地显示了当前的时间(如图1)。

清单2 - Views\Home\Index.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title>Index</title>

</head>

<body>

<div> The current time is: <%= DateTime.Now.ToString("T") %> </div>

</body>

</html>

图1 - Cached Index view



如果你通过输入URL Home/Index到地址栏然后在浏览器里重复地单击刷新按钮来调用Index()行为,那么Index视图里显示的时间将在10秒钟内不会改变。由于视图被缓存了,相同的时间总是被显示。

相同的视图是被缓存给每一个访问你应用的访客是很重要的。任何调用Index()行为的人都将会得到相同缓存版本的Index视图。这意味着Web服务器需要服务Index视图的总工作量显著地被减少了。

清单2的视图恰巧是做一些非常简单的事情。这个视图只是显示了当前的时间。然而,你可以也像这样简单地缓存显示数据库记录的记录集。在这种情况下,每一次返回视图的行为控制器被调用时,数据库记录不再需要从数据库检索。缓存可以降低你的Web服务器和数据库服务器需要执行的工作量。

不要在一个MVC视图里使用页面指令<%@ OutputCache %>。这条该死的指令来自Web Forms世界因而不应该在一个ASP.NET MVC应用里使用。

内容被缓存在哪里
默认情况下,在你使用[OutputCache]属性的时候,内容被缓存在三个地方:Web服务器、代理服务器和浏览器。你可以通过修改[OutputCache]属性(attribute)的Location属性精确地控制内容缓存的地方。

你可以设置Location属性为下面的任意值:

Any
Client
Downstream
Server
None
ServerAndClient

默认情况下,Location属性的值是Any。然而,存在你只想缓存到浏览器或服务器的情况。举例来说,如果你想缓存每个用户个性化的信息,那么就不应该缓存信息到服务器。如果你想显示不同的信息到不同的用户那么你应该缓存信息到客户端。

例如,清单3的控制器暴露了一个名叫GetName()的返回当前用户名字的行为。如果Jack登录了该网站然后调用了GetName()行为那么该行为返回字符串"Hi Jack"。如果,随后,Jill登录了该网站然后调用了GetName()行为那么她也会获得同样的字符串"Hi Jack"。这个字符串在Jack最初调用控制器行为的时候被缓存在Web服务器给所有的用户

清单3 - Controllers\BadUserController.cs

using System.Web.Mvc;

using System.Web.UI;

namespace MvcApplication1.Controllers

{

public class BadUserController : Controller

{

[OutputCache(Duration = 3600, VaryByParam = "none")]

public string GetName()

{

return "Hi " + User.Identity.Name;

}

}

}

最有可能的是,清单3的控制器不像你想的那样工作。你不会想显示"Hi Jack"给Jilll。

你永远都不应该在服务器缓存里缓存个性化内容。但你可能想要在浏览器缓存里缓存个性化的内容来提升性能。如果你在浏览器端缓存内容,并且一个用户调用几次了同样的控制器行为,那么该缓存内容可以从浏览器缓存检索到而不是从服务器端缓存检索。

清单4修改过的控制器缓存了GetName()行为的输出。但是,这些内容仅仅被缓存到浏览器端而不是服务器端。通过这种方式,在多个用户调用GetName()方法的时候,每个人得到他们自己的名字而不是其他用户的用户名。

清单4 - Controllers\UserController.cs

using System.Web.Mvc;

using System.Web.UI;

namespace MvcApplication1.Controllers

{

public class UserController : Controller

{

[OutputCache(Duration=3600, VaryByParam="none", Location=OutputCacheLocation.Client, NoStore=true)]

public string GetName()

{

return "Hi " + User.Identity.Name;

}

}

}

注意清单4的[OutputCache]属性包含了一个值设为OutputCacheLocation.Clientd的Location属性。[OutputCache]属性页包含了一个NoStore属性。NoStore属性被用来通知代理服务器和浏览器它们不应该缓存一个永久的缓存内容的拷贝。

不同的输出缓存
在一些情形下,你可能想要不同缓存版本的非常相似的内容。想象一下,你正在创建一个母版/详细页面。母版页没显示一个电影标题的列表。当你点击一个标题,你会得到选择到的电影的具体内容。

如果你缓存详细页面,那么无论你点击哪个电影标题,都只会显示同一个电影的具体内容。第一个用户选择的第一个电影会被显示给所有的用户。

利用[OutputCache]属性的VaryByParam属性你可以修复这个问题。这个属性允许你在表单参数或查询字符串参数不同的时候创建具有非常相似内容的不同缓存的版本。

例如,清单5的控制器暴露了两个名叫Master()和Detials()的行为。Master()行为返回了一个电影标题的列表而Detail()行为返回了被选中的电影的具体信息。

清单5 - Controllers\MoviesController.cs

using System.Linq;

using System.Web.Mvc;

using MvcApplication1.Models;

namespace MvcApplication1.Controllers

{

public class MoviesController : Controller

{

private MovieDataContext _dataContext;

public MoviesController()

{

_dataContext = new MovieDataContext();

}

[OutputCache(Duration=int.MaxValue, VaryByParam="none")]

public ActionResult Master()

{

ViewData.Model = (from m in _dataContext.Movies

select m).ToList();

return View();

}

[OutputCache(Duration = int.MaxValue, VaryByParam = "id")]

public ActionResult Details(int id)

{

ViewData.Model = _dataContext.Movies.SingleOrDefault(m => m.Id == id);

return View();

}

}

}

Master()行为包含了一个值为"none"的VaryByParam属性。在Master()行为被调用的时候,相同缓存版本的Master视图被返回。任何参数或查询字符传参数都被忽略(如图2)。

图2 - The /Movies/Master view



图3 - The /Movies/Details view



Details()行为包含了值为"Id"的VaryByParam属性。在不同的Id参数的值被传入到控制器行为后,缓存的不同版本的Details视图被生成了。

很重要的一点就是要理解使用VaryByParam属性的后果是使用更多的缓存而不是更少。不同版本的缓存在Details视图中不同版本的Id参数被传入后被创建。

你可以将VaryByParam属性设置成下列的值:

* =在表单的参数或查询字符串参数不同的时候创建一个不同版本的缓存。

none = 从不创建不同版本的缓存。

以分号分割的参数列表=在列表的任何表单或查询字符串参数不同的时候创建不同的缓存版本。

创建一个缓存文件
作为修改[OutputCache]属性(attribute)的属性(properties)另外一种配置输出缓存属性的可选方法,你可以在Web配置文件(Web.config)里创建一个缓存文件。在Web配置文件里创建一个缓存文件为你提供了一系列的重要的好处。

第一,通过在Web配置文件配置输出缓存,你可以控制控制器如何在一个中心的位置缓存内容。你可以创建一个缓存文件然后将该文件应用到几个控制器或控制器行为。

第二,你可以修改Web配置文件而不用重编译你的应用。如果你需要禁用一个已经部署到生产的应用的缓存,那么你可以简单地修改定义在Web配置文件的缓存文件。任何Web配置文件的改变都会被自动地检测并被应用。

例如,清单6的<caching>web配置节点定义了一个名叫Cache1Hour的缓存文件。<caching>节点必须和<system.web>节点一起出现在一个web配置文件。

清单6 - Caching section for web.config

<caching>

<outputCacheSettings>

<outputCacheProfiles>

<add name="Cache1Hour" duration="3600" varyByParam="none"/>

</outputCacheProfiles>

</outputCacheSettings>

</caching>

清单7的控制器描述了利用[OutpucCache]属性你可以怎样使用将Cache1Hour profile应用到一个控制器行为。

清单7 - Controllers\ProfileController.cs

using System;

using System.Web.Mvc;

namespace MvcApplication1.Controllers

{

public class ProfileController : Controller

{

[OutputCache(CacheProfile="Cache1Hour")]

public string Index()

{

return DateTime.Now.ToString("T");

}

}

}

如果你想调用在清单7里的控制器暴露的Index()行为,那么相同的时间会被返回一个小时之久。

总结
输出缓存提供给了你一个非常简单的方式来显著提高你的ASP.NET MVC应用的性能。在这篇教程里,你学习了如何使用[OutputCache]属性来缓存控制器行为的输出。你也学习了如何修改[OutputCache]里诸如Duration和VaryByParam属性来修改内容是如何被缓存的。最后,你学习了如何在web配置文件定义缓存文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: