65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET Core 1.0 中的响应缓存和内存缓存

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.33/5 (2投票s)

2016年7月8日

CPOL

5分钟阅读

viewsIcon

27647

ASP.NET Core 1.0 中的响应缓存和内存缓存

引言

ASP.NET 5 支持几种缓存机制来提高应用程序的性能和响应速度。以下是在不同级别实现缓存的几种选项。

  • 响应缓存
  • 内存缓存
  • SQL Server 中的分布式缓存或内存缓存服务器

目前,ASP.NET 5 不支持输出缓存,但将在未来版本中添加。本文将探讨响应缓存和内存缓存。

响应缓存

如果我们使用 `ResponseCache` 属性修饰 Action、Controller 或全局级别,响应缓存会在应用程序的响应中添加与缓存相关的标头。与早期版本的 ASP.NET 中的输出缓存不同,`ResponseCache` 不会在服务器上存储 HTTP 响应。它只是在响应中添加 "Cache-Control" 标头,现在由客户端选择是否在浏览器或任何中间服务器中缓存响应。如果浏览器或缓存服务器缓存了之前的响应,它可以减少服务器往返次数。在此示例中,我们使用 "ResponseCache" 属性修饰了 `ResponseCache` Action,该属性接受 `Duration` 参数。

        [ResponseCache(Duration =60)]
        public ActionResult ResponseCache()
        {
            return View("Index");
        }

在响应中,我们看到 Cache-Control 标头已添加到 HTTP 响应中

Cache-Control 标头的值可以是 Public、Private 或 no-cache。让我们逐一讨论。

Public

表示响应允许任何缓存机制进行缓存。大多数情况下,如果页面与用户无关,我们可以使其公开可缓存。

Private

Cache-Control 标头的值为 "private",这意味着任何中间缓存服务器都不会缓存它。我们可以将 "Location = ResponseCacheLocation.Client" 与 ResponseCache 一起指定,使其成为私有的。

        [ResponseCache(Duration =60 , Location = ResponseCacheLocation.Client)]
        public ActionResult ResponseCache()
        {
            
                        return View("Index");
        }

在响应中,我们看到 "Cache-Control" 标头的值为 private。因此,响应仅允许在用户的私有区域(如浏览器)中进行缓存。

无缓存

如果我们不想将响应缓存到任何缓存层,可以将 `Location` 值指定为 none。以下是示例代码。

        [ResponseCache(Duration =60 , Location = ResponseCacheLocation.None)]
        public ActionResult ResponseCache()
        {
            return View("Index");
        }

用于缓存的附加 HTTP 标头包括 "Pragma" 和 "Vary",下面将进行说明。从规范中了解更多关于 HTTP 缓存的信息。

ResponseCache 属性

ResponseCache 属性支持许多参数,本节将逐一介绍。
Duration: 类型 int
响应应缓存的最大时间(以秒为单位)。除非 `NoStore` 为 true,否则此项是必需的。
Location: 类型 ResponseCacheLocation
响应可以缓存的位置。可以是 Any、None 或 Client。默认值为 Any。根据此值,"Response-Cache" 标头的值会发生变化。
NoStore : 类型 bool
确定是否应存储值,并覆盖其他属性值。当为 true 时,Duration 被忽略,Location(除 None 外)也被忽略。No Store 的常见场景可能是显示错误页面。错误页面通常是用户特定的,我们不希望将一个用户生成的错误页面显示给另一个用户。
VaryByHeader : 类型 string
设置时,响应中会写入 vary 响应标头。当标头的值发生变化时,缓存的版本将失效。
CacheProfileName : 类型 string
设置时,确定要使用的缓存配置文件的名称。我们可以在 ASP.NET 5 应用程序的 Configuration 部分指定缓存配置文件。
Order int
过滤器的顺序(来自 IOrderedFilter)。

缓存配置文件

我们可以在应用程序级别维护缓存配置文件,并在 Action 或 Controller 级别使用。该机制将减少代码重复。在此示例中,我们创建了一个名为 "private cache" 的缓存配置文件。

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(options =>
            {
                options.CacheProfiles.Add("PrivateCache",
                    new CacheProfile()
                    {
                        Duration = 60,
                        Location = ResponseCacheLocation.None
                    });
                
            });
            services.AddCaching();
        }

现在,我们可以在 Controller/Action 级别使用该配置文件。以下是实现此功能的示例代码。

        [ResponseCache(CacheProfileName = "PrivateCache")]
    
        public ActionResult ResponseCache()
        {
            return View("Index");
        }

内存缓存

内存缓存使用分配给进程的内存来存储信息。它不是分布式的,也不是可伸缩的,因为缓存数据存储在服务器进程中。要配置内存缓存,我们需要在 project.json 文件中添加以下包。

    "Microsoft.Extensions.Caching.Memory": "1.0.0-rc1-final",
    "Microsoft.Extensions.Caching.Abstractions": "1.0.0-rc1-final"

ASP.NET Core 中的缓存是一项服务,应通过依赖注入从应用程序中引用。要在应用程序中注册缓存服务并使其可用,请在 Startup.cs 文件的 ConfigureServices 方法中添加以下行。以下是示例代码。

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddCaching();
        }

获取和设置内存缓存的值

在此示例中,我们将学习如何获取和设置内存缓存的值。要获取值,我们可以使用 `Get` 或 `TryGateValue()` 函数。要设置值,我们可以使用 `Set()` 函数。以下是完整的内存缓存代码示例。

        public class HomeController : Controller
    {
        private IMemoryCache cache;
        private static int data;
        public HomeController(IMemoryCache cache)
        {
            this.cache = cache;
        }
        public ActionResult Index()
        {
                var Time =  DateTime.Now.ToLocalTime().ToString() ;
                this.cache.Set("Time", Time, new MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = (DateTime.Now.AddMinutes(1) - DateTime.Now  ) });
                ViewBag.Time = Time;
                return View();
        }
        public IActionResult GetCache()
        {
            string Time = null;
            if (this.cache.TryGetValue("Time", out Time))
            {
                ViewBag.Time = Time;
            }
            else
                ViewBag.Time = DateTime.Now.ToLocalTime().ToString();
            return View("Index");
        }

Index Action 会将当前日期时间缓存起来,当我们调用 GetCache() 函数时,它首先检查缓存。 如果缓存存在,则从缓存返回;否则,将返回新的日期时间。缓存的持续时间为一分钟,因为在缓存设置时我们已指定了值。

        this.cache.Set("Time", Time, new MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = (DateTime.Now.AddMinutes(1) - DateTime.Now  ) });

AbsoluteExpirationRelativeToNow 属性中。下面显示了设置过期值的另一种方法。

        _this.cache.Set("key", "Value", new MemoryCacheEntryOptions()         .SetAbsoluteExpiration(TimeSpan.FromMinutes(1)));

设置缓存优先级

默认情况下,MemoryCache 实例会根据应用程序内存压力自动管理存储的项目,在必要时删除条目。您可以通过在将项目添加到缓存时设置其 CacheItemPriority 来影响缓存条目的管理方式。例如,如果您有一个想要保留在缓存中直到显式删除的项目,您可以使用 NeverRemove 优先级选项。

        new MemoryCacheEntryOptions()
      .SetPriority(CacheItemPriority.NeverRemove))

如果您想显式删除缓存条目,可以像这样调用 `remove()` 函数。cache.Remove("Key");

结论

响应缓存允许客户端在各种缓存级别缓存响应,而内存缓存允许在进程内存中进行缓存。但是,它们本质上不是分布式的,也不是可伸缩的。ASP.NET 5 还支持分布式缓存,我们可以将缓存数据存储在 SQL 或 Redis 集群中。

© . All rights reserved.