不同的ASP.NET缓存选项的优缺点

56

我最近在一个ASP.NET MVC WebAPI应用程序中询问了有关缓存应用数据的问题,这使我产生了一个新问题。ASP.NET中可用的不同缓存方法的优缺点是什么?

我已经发现以下内容:

  • 内存缓存

    http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx

  • 使用静态成员变量:

    private static Northwind.SuppliersDataTable suppliers = null;
    
  • 应用程序状态:

  •  HttpContext.Current.Application["key"] ="Value"
    
  • 数据缓存:

    HttpRuntime.Cache.Insert(
      /* key */                "key", 
      /* value */              "value", 
      /* dependencies */       null, 
      /* absoluteExpiration */ Cache.NoAbsoluteExpiration, 
      /* slidingExpiration */  Cache.NoSlidingExpiration, 
      /* priority */           CacheItemPriority.NotRemovable, 
      /* onRemoveCallback */   null);
    

我相信还有其他的方式,而且我知道它们都技术上将数据存储在内存中...那么你有什么建议用于ASP.NET MVC WebAPI的缓存吗?

我的之前的问题: 将应用程序数据缓存在内存中:MVC Web API


这要看情况,你可以说出你想做什么,但是我不喜欢使用“Application”条目。我更喜欢使用“IDictionary<string, object>”。如果你可以重新制作数据,那么“Cache”也是可以的。 - Felipe Oriani
3个回答

34
每种缓存技术/方法都有其自己的一套特点。这些特点在某些应用要求下可能会带来不利影响,但在其他应用要求下则可能具有优势。
因此,简而言之,根据您的需求决定使用哪种缓存技术以及哪些特点最适合您。
例如,让我们讨论一些客户端缓存技术。MSDN表示,我们还可以使用 HiddenField 在隐藏字段中存储只包含小量经常变化数据的信息,因为每次 postback 请求都会将这些数据包含在其中。
此功能的优点是:通过使用客户端选项存储页面信息,可以减轻服务器工作量。但 MSDN 明确指出,此方法的安全支持非常少。
因此,由于存在安全考虑,人们可能并不总是使用此功能。
再看一个例子,页面输出缓存有 2 种类型:页面输出缓存和页面片段缓存。页面输出缓存会缓存整个 Web 页面,仅适用于页面内容相对静态的情况。如果页面的某些部分正在更改,则可以将静态部分封装为用户控件,并使用页面片段缓存缓存用户控件。
最后,关于 Application vs HttpRuntime.cache 的最后一条评论:
Application 不是缓存,而是全局命名值集合。如果将对象添加到 Application 中,它将一直保留,直到应用程序域回收。
应用程序变量是 Web 应用程序所有用户共享的变量。应用程序变量的行为类似于静态变量,并且它们是静态变量在 Web 应用程序中的替代品,因为静态变量在 Web 应用程序中是无状态的。
只有共享值应该持久保存在应用程序变量中,并且一旦不再使用它们,就应该明确地将它们删除。

缓存 :在ASP.NET应用程序中,通过使用ApplicationCache类来缓存经常请求的对象和数据,可以获得显着的性能提升。虽然Cache类在灵活性和控制方面提供了更多的优势,但就缓存而言,相对于Application类只提供了轻微的吞吐量增加优势。这很难开发一个测试方案,准确地测量Cache类通过清理进程管理较少使用的对象与Application不提供此功能之间的潜在优势。在这种情况下,开发人员需要根据项目的需求和使用模式做出决策。有关更多信息,请参见此链接

请参考此MSDN文章,详细介绍了Asp.net中所有缓存技术的优缺点和特点。

此外,以下两个链接是开始学习的好资源:


2
非常棒的概述!尽管您的评论主要针对asp.net网站而不是webapi,但您列出的msdn网络文章有很多惊人的信息。 - vesuvious
@Interstellar:链接通常会失效...我尝试在我的回答中包含尽可能多的细节,但不想让它变得太冗长。MSDN链接和第一个链接都可以正常工作,其中包含了大部分有价值的信息。您还可以在Peter Johnson的博客上搜索任何内容,网址为:https://weblogs.asp.net/pjohnson - R.C
http://weblogs.asp.net/pjohnson/437559 找不到。 - PreguntonCojoneroCabrón
1
修复链接,作者为_P Johnson_:https://weblogs.asp.net/pjohnson/httpruntime-cache-vs-httpcontext-current-cache - PreguntonCojoneroCabrón

10

关于 MemoryCache 和 ASP.NET Cache:它们提供非常相似的功能。在ASP.NET 4应用程序中,我通常更喜欢使用ASP.NET Cache,即使没有其他原因,那也是因为.NET 4 中存在的一个 bug ,这个问题显然在 .NET 4.5 中已经得到了修复。

静态字段适合存储不需要过期策略的共享数据。

应用程序状态本质上只是一个带有锁定语义的静态字典,与经典 ASP 兼容 - 我只会将其用于与传统 ASP 代码向后兼容。


你知道这两种缓存方法是否在 IIS 工作线程超时后是持久的吗? - vesuvious
1
@vesuvious - 是的,它们将在请求超时期间持续存在:这样的超时对静态字段没有影响。它们将在应用程序域被回收时清除。 - Joe

4

在使用Web API时,您应该始终将缓存头设置在HTTP响应中,HttpResponseMessage.CacheControlHeader是您的首选。

最后的选择应该是依赖于 HttpContextHttpRuntime 的任何内容,因为这将使您与特定的主机绑定。Web API 应用程序应该独立于其主机构建。


你的意思是最后一个选项 不应该 吗? - user20358
@user20358 我的意思是,在尝试使用依赖于主机的机制进行优化之前,应该首先尝试并使用不依赖于主机的优化。 - Darrel Miller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接