ASP.NET Core中的内存中缓存

让我们看看如何通过缓存优化ASP.NET Core应用程序性能

我相信,在我们的工作中,每个人都收到来自客户的请求或来自我们应用程序用户的反馈,以提高响应速度。

如果在编写代码时仅使用最佳实践还不够,那么我们肯定需要使用缓存来微调我们的应用程序。

缓存包括将那些不经常更改的信息存储在某个地方。高频访问是我们应用程序的业务要求。

在本文中,我们将看到ASP.NET Core可用于缓存的内容。

IMemoryCache和IDistributedCache

这两个接口代表.NET Core中用于缓存的内置机制。您可能已经听说过的所有其他技术都是这两个接口的实现。在本文中,我们将详细介绍内存缓存,而在以后的文章中将研究分布式缓存。

在ASP.NET Core中启用内存中缓存

我们可以使用ConfigureServices方法将ASP.NET内存中缓存合并到应用程序中。您可以在Startup类中启用MemoryCache,如下面的代码片段所示。

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

AddMemoryCache方法允许我们注册IMemoryCache接口,如上面提到的,将被用于高速缓存的基础。下面我们看到框架中接口的定义:

public interface IMemoryCache : IDisposable
{bool TryGetValue(object key, out object value);ICacheEntry CreateEntry(object key);void Remove(object key);
}

接口中提供的方法并不是唯一可用于缓存的方法:我们将在后面看到,存在各种扩展来丰富可用的API并极大地促进其使用。例如:

public static class CacheExtensions
{public static TItem Get<titem>(this IMemoryCache cache, object key);public static TItem Set<titem>(this IMemoryCache cache, object key, TItem value, MemoryCacheEntryOptions options);public static bool TryGetValue<titem>(this IMemoryCache cache, object key, out TItem value);...
}

注册后,该接口可以注入到我们要使用它的类构造函数中,如下所示:

private IMemoryCache cache;
public MyCacheController(IMemoryCache cache){this.cache = cache;}

在下面的部分中,我们将研究如何在ASP.NET Core中使用缓存API来存储和检索对象。

使用IMemoryCache存储和检索项目

要使用IMemoryCache接口写入对象,请使用Set ()方法,如以下代码片段所示。

[HttpGet]
public string Get()
{cache.Set(“MyKey”, DateTime.Now.ToString());return “This is a test method...”;
}

此方法接受两个参数,第一个是键,用于标识缓存的对象,第二个参数是我们要存储的值。要从缓存中检索对象,请使用Get ()方法,如下面的代码片段所示。

[HttpGet(“{key}”)]
public string Get(string key)
{return cache.Get<string>(key);
}

如果我们不确定缓存中是否存在特定的密钥,则可以使用TryGetValue()方法进行帮助:它返回一个布尔值,指示所请求的密钥存在或不存在。

下面是如何使用TryGetValue修改Get()方法的方法。

[HttpGet(“{key}”)]
public string Get(string key)
{string obj;if (!cache.TryGetValue<string>(key, out obj))obj = DateTime.Now.ToString();cache.Set<string>(key, obj);return obj;
}

可用的另一种方法是GetOrCreate()方法,该方法验证所需密钥的存在,否则,该方法将为您创建它。

[HttpGet(“{key}”)]
public string Get(string key)
{return cache.GetOrCreate<string>(“key”,cacheEntry => {return DateTime.Now.ToString();});
}

如何在ASP.NET Core中的缓存数据上设置过期策略

当我们使用IMemoryCache存储对象时,MemoryCacheEntryOptions类为我们提供了各种技术来管理缓存数据的到期时间。

我们可以指定一个固定的时间,在该时间之后某个特定的密钥将过期(绝对过期),或者如果在某个特定的时间(滑动过期)之后没有访问它,则它可以过期。此外,还可以使用Expiration Token在缓存的对象之间创建依赖关系。这里有一些例子

//absolute expiration using TimeSpan
_cache.Set("key", item, TimeSpan.FromDays(1));//absolute expiration using DateTime
_cache.Set("key", item, new DateTime(2020, 1, 1));//sliding expiration (evict if not accessed for 7 days)
_cache.Set("key", item, new MemoryCacheEntryOptions
{SlidingExpiration = TimeSpan.FromDays(7)
});//use both absolute and sliding expiration
_cache.Set("key", item, new MemoryCacheEntryOptions
{AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(30),SlidingExpiration = TimeSpan.FromDays(7)
})// This method adds a trigger to refresh the data from background
private void UpdateReset()
{var mo = new MemoryCacheEntryOptions();mo.RegisterPostEvictionCallback(RefreshAllPlacessCache_PostEvictionCallback);mo.AddExpirationToken(new CancellationChangeToken(new CancellationTokenSource(TimeSpan.FromMinutes(35)).Token));Cache.Set(CACHE_KEY_PLACES_RESET, DateTime.Now, mo);
}// Method triggered by the cancellation token that triggers the PostEvictionCallBack
private async void RefreshAllPlacesCache_PostEvictionCallback(object key, object value, EvictionReason reason, object state)
{// Regenerate a set of updated datavar places = await GetLongGeneratingData();Cache.Set(CACHE_KEY_PLACES, places, TimeSpan.FromMinutes(40));// Re-set the cache to be reloaded in 35minUpdateReset();
}

缓存回调

MemoryCacheEntryOptions类提供的另一个有趣功能是允许我们注册回调的功能,当从缓存中删除一项时将执行该回调。

MemoryCacheEntryOptions cacheOption = new MemoryCacheEntryOptions()
{  AbsoluteExpirationRelativeToNow = (DateTime.Now.AddMinutes(1) - DateTime.Now),
};
cacheOption.RegisterPostEvictionCallback(  (key, value, reason, substate) =>  {  Console.Write("Cache expired!");  });

缓存标签助手

到目前为止,我们已经看到.NET Core提供的API的使用,从而能够直接使用IMemoryCache接口手动在缓存中写入和读取项目。此接口还有其他实现,可能非常有用。例如,在Web环境中,如果我们使用.NET Core MVC框架,则可以使用helper cache tag存储部分页面。它非常简单易用:您可以将视图的一部分包装在缓存标签中以启用缓存:

<cache>
<p>Ora: @DateTime.Now</p>
</cache>

对于页面的每个后续请求(包含此标记),将从缓存中使用该段的正文。如果将其放在页面上并观察其输出,则可以轻松检查行为。当然,我们使用它的方式仅出于示例目的,但是当您尝试渲染需要大量资源的页面时,您可以欣赏它的功能。一个明显的缓存候选是视图组件[1]调用

<cache expires-on="@TimeSpan.FromSeconds(600)">
@await Component.InvokeAsync("BlogPosts", new { tag = "popular" })
</cache>

在上一个代码段中,您还可以通过属性expires-on来了解如何管理缓存中对象的过期期限。还有其他两种选择:

•过期时间:将使用TimeSpan进行评估以指示一段时间,此后必须重新生成内容;•过期滑动:还应使用指示闲置时间的TimeSpan。每次从缓存中读取内容时,都会将其删除延迟。

另一个可定制方面涉及配置缓存标准的可能性。我们可能需要根据一些变量来更新缓存的对象。一些要求是由覆盖变化经过下列属性:

•按路由变化:通过路由参数的名称(例如id)进行了增强,以指示在指示的属性更改时必须重新生成内容;•因查询而异:当更改查询字符串键时,将生成并缓存内容;•按用户不同:当我们显示已登录用户的特定数据时(例如,包含名称和照片的个人资料框),必须将其设置为true;•按标题变化:如果我们使用HTTP请求标头显示语言内容,则根据HTTP请求标头来更改缓存,例如“ Accept-Language”。•cookie-variable-by-cookie:允许您根据cookie的内容更改缓存,我们必须指出其名称。

可以使用一个或多个按属性的属性来执行高级缓存策略,但是,有句著名的名言:“功能强大,责任重大”。

结论

使用内存缓存可以使您将数据存储在服务器的内存中,并通过删除对外部数据源的不必要请求来帮助我们提高应用程序性能。如我们所见,它非常易于使用。

我提醒您,当您的应用程序托管在多台服务器或云托管环境中时,不能使用这种方法。在下一篇文章中,我们将讨论分布式缓存。

下次见!

References

[1] 组件: https://www.blexin.com/en-US/Article/Blog/Kestrel-build-me-up-31

ASP.NET Core中的内存缓存相关推荐

  1. ASP.NET Core中的分布式缓存

    ASP.NET Core中的分布式缓存 在上一篇文章中[1],我解释了如何使用内存缓存在ASP.NET Core应用程序中管理缓存.如果您的应用程序托管在单个服务器上,则可以使用这种类型的缓存.那.N ...

  2. ASP.NET Core中的Http缓存

    ASP.NET Core中的Http缓存 Http响应缓存可减少客户端或代理对 web服务器发出的请求数.响应缓存还减少了 web服务器生成响应所需的工作量.响应缓存由 Http请求中的 header ...

  3. asp.net core webapi Session 内存缓存

    Startup.cs文件中的ConfigureServices方法配置: #region Session内存缓存 services.Configure<CookiePolicyOptions&g ...

  4. 如何在 ASP.Net Core 中使用 NCache

    虽然 ASP.Net Core 中缺少 Cache 对象,但它引入了三种不同的cache方式. 内存缓存 分布式缓存 Response缓存 Alachisoft 公司提供了一个开源项目 NCache, ...

  5. .ASP NET Core中缓存问题案例

    本篇博客中,我将描述一个关于会话状态(Session State)的问题, 这个问题我已经被询问了好几次了. 问题的场景 创建一个新的ASP.NET Core应用程序 一个用户在会话状态中设置了一个字 ...

  6. Api网关Kong集成Consul做服务发现及在Asp.Net Core中的使用

     1622219047536 写在前面   Api网关我们之前是用 .netcore写的 Ocelot的,使用后并没有完全达到我们的预期,花了些时间了解后觉得kong可能是个更合适的选择. 简单说下 ...

  7. Asp.Net Core 中IdentityServer4 实战之角色授权详解

    一.前言 前几篇文章分享了IdentityServer4密码模式的基本授权及自定义授权等方式,最近由于改造一个网关服务,也用到了IdentityServer4的授权,改造过程中发现比较适合基于Role ...

  8. 为什么我的会话状态在ASP.NET Core中不工作了?

    原文:Why isn't my session state working in ASP.NET Core? Session state, GDPR, and non-essential cookie ...

  9. 在ASP.NET Core中使用brotli压缩

    Brotli是一种全新的数据格式,可以提供比Zopfli高20-26%的压缩比.据谷歌研究,Brotli压缩速度同zlib的Deflate实现大致相同,而在Canterbury语料库上的压缩密度比LZ ...

最新文章

  1. Linux_学习_01_常用命令大全
  2. linux 重定向_Unix/Linux编程实践之IO重定向和管道
  3. OpenGL noperspective在窗口空间中线性插值的实例
  4. java调度:(三)Timer中的单线程守护
  5. 有道智能学习灯 初体验
  6. MessagePack Jackson 数据大小
  7. 一步一步写算法(之prim算法 下)
  8. leetcode力扣75. 颜色分类
  9. PowerDesigner生成SQL
  10. Spring+SpringMVC+mybatis+Quartz整合
  11. [Vmware]IP配置方式
  12. 深入Atlas系列:客户端网络访问基础结构(上) - WebRequest的工作流程与生命周期...
  13. 使用go语言开发一个后端gin框架的web项目
  14. nsis出错_安装程序出现NSIS ERROR错误解决思路
  15. 互联网晚报 | 1月7日 星期五 | 微信小程序日活突破4.5亿;阿里调整大淘宝组织架构;丰田成2021年美国最畅销汽车品牌...
  16. 华为员工待遇全面揭秘
  17. Kubernetes Events介绍(中)
  18. CentOS7 配置与管理DHCP服务器及DHCP中继代理 DHCP服务实训整合
  19. uniapp 小程序开发,实现图片直传阿里云的简单方法
  20. 递归、迭代和分治(1):递归

热门文章

  1. 《解密小米之互联网下的商业奇迹》
  2. JavaScript数组迭代方法(图解)
  3. 大型网站架构演化(二)——应用服务和数据服务分离
  4. Meta http-equiv属性详解
  5. Android:源码环境编译自定义的APP到ROM(System Image)中
  6. 关于castle和Could not find the dialect in the configuration错误
  7. div方框弯曲边样式_使用弯曲样式编辑文本
  8. 『中级篇』Dockerfile详解(17)
  9. com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
  10. hdu 1848(Fibonacci again and again)(SG博弈)