1. 整体说明

  ASP.NET Core 支持多种不同的缓存,最简单的缓存基于 IMemoryCache,它表示存储在 Web 服务器内存中的缓存,内存缓存可以存储任何对象,存储形式键值对,需要 .net standard 2.0 或者 .Net framework 4.5 或更高版本。

本节主要介绍:依赖注入的方式使用、全局封装单例配置、缓存几个方法和性质。

2. 常规使用步骤

  (1) 安装程序集:System.Runtime.Caching 和 Microsoft.Extensions.Caching.Memory,如果是是Core MVC程序自带的Microsoft.AspNetCore.App包里已经涵盖了

Microsoft.Extensions.Caching.Memory,无需重复下载。

  (2) 在ConfigureService中注册内存缓存服务: services.AddMemoryCache();

 using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMemoryCache();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
} }

  (3) 通过属性注入的方式在控制器中注入IMemoryCache对象。

  public class FirstController : Controller
{
private IMemoryCache _cache1;
public FirstController(IMemoryCache memoryCache)
{
_cache1 = memoryCache;
}
}

  (4) 通过get、set方法实现常规缓存的读取和写入,如下 案例①。

    {
string nowTime1 = _cache1.Get<string>("t1");
if (String.IsNullOrEmpty(nowTime1))
{
nowTime1 = DateTime.Now.ToString();
_cache1.Set("t1", nowTime1);
}
ViewBag.t1 = nowTime1;
}

3. 全局封装单例的形式

 (1)新建一个memoryCacheHelp类,声明一个IMemoryCache属性,并在构造函数中进行初始化,实例化的时候可以通过SizeLimit设置全局缓存的最大Size。

特别注意:如果在这全局设置了最大Size,凡是使用的时候都需要通过SetSize进行设置,且必须 "小于等于" 这个最大Size,不设置会报错,设置的比这个大,缓存会失效。

  public class memoryCacheHelp
{
public IMemoryCache _cache { get; set; }
public memoryCacheHelp()
{
_cache = new MemoryCache(new MemoryCacheOptions {
SizeLimit =
});
}
}

 (2)在ConfigureService将该类注册成单例的:services.AddSingleton<memoryCacheHelp>();

 public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSingleton<memoryCacheHelp>();
}

 (3)通过属性注入的方式在控制器中注入IMemoryCache对象

  public class FirstController : Controller
{
private IMemoryCache _cache2;
public FirstController(memoryCacheHelp cache)
{
_cache2 = cache._cache;
}
}

 (4)通过TryGetValue、set方法实现缓存的读取和写入,如下 案例②

注: 这里通过依赖注入的形式将memoryCacheHelp注册成单例类,和直接声明成单例类道理是一样的。

  {
string nowTime2 = null;
if (!_cache2.TryGetValue("t2", out nowTime2))
{
nowTime2 = DateTime.Now.ToString();
//设置缓存的大小
var cacheOptions = new MemoryCacheEntryOptions()
.SetSize()
.SetAbsoluteExpiration(TimeSpan.FromSeconds());
_cache2.Set("t2", nowTime2, cacheOptions);
}
ViewBag.t2 = nowTime2;
}

4. 方法、属性详解

(1) 获取数据

 A. Get<T>方法:根据键名获取指定类型的值,将返回值做判断,比如根据是否为null,来判断有没有值。 如下面的案例①

 B. TryGetValue(object key, out TItem value);根据key获取指定类型值,通过out参数进行输出,如果拿到值返回true,如果拿不到值返回false,相比Get<T>方法 如下面案例②

 C. GetOrCreate(object key, Func<ICacheEntry, TItem> factory);适用场景:key有值则获取该值,没有值为它赋值(通过return直接返回)。如下面案例③

(2) 写入数据

 A. Set方法:有很多重载,重点看下面两个

  ①:Set<TItem>(object key, TItem value); 最简单的键值模式

  ②:Set<TItem>(object key, TItem value, MemoryCacheEntryOptions options); 通过MemoryCacheEntryOptions设置缓存的性质,详见下面

 B. GetOrCreate方法:当key对应的值为空则通过return返回来赋值,如下面的:案例③,通过第二个参数在Func委托中设置ICacheEntry属性进行缓存性质的设置。 详见下面(5)

 {
string nowTime3 = _cache1.GetOrCreate("t3", entry =>
{
entry.Size = ;
//滑动过期时间设置为2秒
entry.SlidingExpiration = TimeSpan.FromSeconds();
//绝对和滑动只能设置一个
//entry.AbsoluteExpiration = new DateTimeOffset(DateTime.Parse("2019-07-16 16:33:10"));
entry.Priority = CacheItemPriority.High;
entry.RegisterPostEvictionCallback(MyCallback, this);
return DateTime.Now.ToString();
});
ViewBag.t3 = nowTime3;
}

(3) 移除数据

 A. Remove方法:Remove(object key); 移除缓存

(4) MemoryCacheEntryOptions类

 用来设置缓存的一些性质,可以通过方法或者属性进行设置,在Set方法中使用。

 A. 缓存大小(SetSize方法和Size属性):如果全局单例设置缓存的最大值,则每个使用的地方都需要显式的设置,必须小于等于最大值,如果不设置报错,如果设置比最大值还大,缓存不生效。

 B. 绝对过期时间(SetAbsoluteExpiration方法和AbsoluteExpiration属性):绝对指的是到了这个时间就过期,不管这期间有没有人访问。

 绝对过期有两种设置方式:① 通过TimeSpan设置距离当前时间的间隔 ② 通过DateTimeOffset设置具体到某一时刻。 详见下面案例④

 C. 滑动过期时间(SetSlidingExpiration方法和SlidingExpiration属性):相对是指以最后一次访问来计算,每访问一次重新计算过期时间。

 D. 缓存级别(SetPriority方法和Priority属性):有Low、Normal、High、NeverRemove。

 E. 缓存移除时回调(RegisterPostEvictionCallback方法和属性):缓存过期或者手动移除时调用,该方法有四个参数,调用的时候自动赋值,分别是: 键、值、消失原因、状态。

   {
string nowTime4 = null;
if (!_cache2.TryGetValue("t4", out nowTime4))
{
nowTime4 = DateTime.Now.ToString();
MemoryCacheEntryOptions cacheOptions = null; //设置缓存方式一:(通过方法)
{
cacheOptions = new MemoryCacheEntryOptions()
.SetSize()
//.SetSlidingExpiration(TimeSpan.FromSeconds(5))
//绝对和滑动只能设置一个
.SetAbsoluteExpiration(TimeSpan.FromSeconds())
.SetPriority(CacheItemPriority.Normal)
.RegisterPostEvictionCallback(MyCallback, this); } //设置缓存方式二:(通过属性)
//{
// cacheOptions = new MemoryCacheEntryOptions();
// cacheOptions.Size = 100;
// //cacheOptions.SlidingExpiration = TimeSpan.FromSeconds(5);
// //绝对和滑动只能设置一个
// cacheOptions.AbsoluteExpiration = new DateTimeOffset(DateTime.Parse("2019-07-16 16:33:10"));
// cacheOptions.Priority = CacheItemPriority.High;
// cacheOptions.RegisterPostEvictionCallback(MyCallback, this);
//}
_cache2.Set("t4", nowTime4, cacheOptions); }
ViewBag.t4 = nowTime4;
} /// <summary>
/// 失败回调
/// </summary>
/// <param name="key">键</param>
/// <param name="value">值</param>
/// <param name="reason">缓存消失的原因,比如移除、过期,是个枚举类型</param>
/// <param name="state"></param>
private static void MyCallback(object key, object value, EvictionReason reason, object state)
{
var message = $"Cache entry was removed : key={key},value={value}, reason={reason}, state={state}";
}

(5) ICacheEntry

 通过属性的形式设置:缓存大小、绝对过期、滑动过期、缓存级别、缓存移除回调,详见案例③

5.即时创建调用 VS 全局单例调用

 首先需要明白,不管即时创建调用还是全局单例调用,MemoryCache都是存在服务器内存中的,这一点是毋庸置疑的。

 (1) 即时创建调用:多个客户端每次访问该方法的时候,都需要现创建一个IMemoryCache对象,然后进行读取或写入。

 (2) 全局单例调用:只要有一个客户端访问该方法,创建IMemoryCache对象,后续不管谁访问,都是使用的同一个对象进行读取或写入。

很傻瓜的一个问题:内存缓存是以键值对的形式进行存储,同一个键如果多次设置会覆盖,但是不同键之间设置过期时间是互相不影响的。

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

第十一节:Asp.Net Core 之内容缓存(IMemoryCache)的更多相关文章

  1. ASP.NET Core中的缓存[1]:如何在一个ASP.NET Core应用中使用缓存

    .NET Core针对缓存提供了很好的支持 ,我们不仅可以选择将数据缓存在应用进程自身的内存中,还可以采用分布式的形式将缓存数据存储在一个“中心数据库”中.对于分布式缓存,.NET Core提供了针对 ...

  2. ASP.NET Core ResponseCache进行缓存操作

    前言 本章将介绍客户端缓存将介绍浏览器缓存和服务端缓存,使用浏览器缓存将减少对web服务器的请求次数,同时可以提升性能,避免重复的运算浪费. ASP.NET Core对于HTTP缓存分为两种: 客户端 ...

  3. ASP.Net Core使用分布式缓存Redis从入门到实战演练

    一.课程介绍 人生苦短,我用.NET Core!缓存在很多情况下需要用到,合理利用缓存可以一方面可以提高程序的响应速度,同时可以减少对特定资源访问的压力.  所以经常要用到且不会频繁改变且被用户共享的 ...

  4. ASP.NET Core 中的缓存

    目录 缓存的基本概念 缓存原理 缓存设计 分布式缓存 Memcache 与 Redis 的比较 缓存穿透,缓存击穿,缓存雪崩解决方案 数据一致性 使用内置 MemoryCache 使用分布式缓存 Re ...

  5. 第十二节:Asp.Net Core 之分布式缓存(SQLServer和Redis)

    一. 整体说明 1. 说明 分布式缓存通常是指在多个应用程序服务器的架构下,作为他们共享的外部服务共享缓存,常用的有SQLServer.Redis.NCache.     特别说明一下:这里的分布式是 ...

  6. 第二十九节: Asp.Net Core零散获取总结(不断补充)

    1. IWebHostEnvironment获取常用属性 (1).获取项目的根目录 _env.ContentRootPath 等价于 Directory.GetCurrentDirectory() ( ...

  7. Asp.net Core CacheHelper 通用缓存帮助类

    using System; using Microsoft.Extensions.Caching.Memory; using System.Runtime; namespace UFX.Tools { ...

  8. asp.net core刷新css缓存

    在非spa程序开发的时候.css经常会因为浏览器的缓存机制导致不刷新. 很多前端为了应对这个问题,都会引入webpack或者gulp等工具来处理css缓存的问题. 但是作为一个偏服务器端的程序员来说. ...

  9. ASP.NET Core 2.0 : 五.服务是如何加载并运行的, Kestrel、配置与环境

    "跨平台"后的ASP.Net Core是如何接收并处理请求的呢? 它的运行和处理机制和之前有什么不同? 本章从"宏观"到"微观"地看一下它的 ...

随机推荐

  1. Qt Examples - Boxes (在Qt场景视图中结合OpenGL渲染)

    QT自带例程Boxes使用QT Graphics View框架实现了2D图形和3D图形的混合渲染,综合性比较强,整合知识较多,值得学习. 可以使用鼠标通过以下方式控制演示中的元素: 按住鼠标左键的同时 ...

  2. CTF——web安全中的一些绕过

    function check($number) { $one = ord('1'); $nine = ord('9'); for ($i = 0; $i < strlen($number); $ ...

  3. APS系统如何落地?用户实际痛点解析!

    APS软件在中国的发展,在很长的时间内处于非常尴尬的状态:大企业都了解APS很重要,但只有非常少的企业肯真正实施APS软件,处于叫好不叫座的状态.直到工业4.0概念流行后,APS才逐渐被国内企业所认可 ...

  4. 6 Linux用户和用户组管理

    Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户都必须首相像系统管理员申请账号,然后以这个账号身份进入系统 每个用户账号都拥有一个唯一的用户名和各自的口令 用户在登陆时键入 ...

  5. WorkFlow四:添加用户决策步骤

    沿用之前的例子,做个用户决策步骤. 1.事物代码SWDD: 进入抬头,点击类的绑定按钮. 2.选择类的绑定,点击继续. 这是类的绑定已经变色了.这时候点击保存,再点击返回到图片逻辑流界面. 3.在发送 ...

  6. 3.redis 都有哪些数据类型?分别在哪些场景下使用比较合适?

    作者:中华石杉 面试题 redis 都有哪些数据类型?分别在哪些场景下使用比较合适? 面试官心理分析 除非是面试官感觉看你简历,是工作 3 年以内的比较初级的同学,可能对技术没有很深入的研究,面试官才 ...

  7. Nginx 核心配置-location的登录账户认证实战篇

    Nginx 核心配置-location的登录账户认证实战篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.使用ab命令模拟网站攻击 1>.安装httpd-tools工具 ...

  8. dapi 基于Django的轻量级测试平台二 前端页面

    QQ群: GitHub:https://github.com/yjlch1016/dapi 一.登录页login.html: 二.首页home.html: 三.产品线列表页product.html: ...

  9. PAT 乙级 1039.到底买不买 C++/Java

    题目来源 小红想买些珠子做一串自己喜欢的珠串.卖珠子的摊主有很多串五颜六色的珠串,但是不肯把任何一串拆散了卖.于是小红要你帮忙判断一下,某串珠子里是否包含了全部自己想要的珠子?如果是,那么告诉她有多少 ...

  10. 数据结构篇——字典树(trie树)

    引入 现在有这样一个问题, 给出\(n\)个单词和\(m\)个询问,每次询问一个单词,回答这个单词是否在单词表中出现过. 好像还行,用 map<string,bool> ,几行就完事了. ...