缓存是一种开发时常用的性能优化手段,.Net自带内存缓存(MemoryCache)可以很方便的使用,下面列出简单用法。

首先通过NuGet添加 Microsoft.Extensions.Hosting、Microsoft.Extensions.Caching.Memory 这两个包。

添加命令:

Install-Package Microsoft.Extensions.Caching.Memory
Install-Package Microsoft.Extensions.Hosting

向缓存中添加数据:

memoryCache.Set(dog.Name, dog, options);

从缓存获取数据(可以直接使用泛型方法指定返回类型):

memoryCache.Get<Dog>(key);

添加时可以使用 await memoryCache.GetOrCreateAsync()方法完成,该方法可以在缓存中没有数据时另外处理获取数据的方式,并将结果添加进缓存中。

一、示例代码

internal class CacheDemo
{
//该集合当做数据源
static IEnumerable<Dog> dogs;
//全局容器
static IHost host;
public static async Task DemoMain()
{
//向容器添加缓存服务
host = Host.CreateDefaultBuilder()
.ConfigureServices(services => services.AddMemoryCache())
.Build(); //向数据源填充数据
dogs = GetDogs().ToList();
//缓存配置
MemoryCacheEntryOptions cacheOptions = new()
{
//设置缓存10秒过期
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(10)
}; //循环查询缓存中是否有对应数据
foreach (Dog dog in GetDogs())
{
var dogResult = await GetDogAsync(dog.Name);
Console.WriteLine($"查询结果1:{dogResult}");
} var dogResult2 = GetCacheData("泰迪");
Console.WriteLine($"查询结果2:{dogResult2}");
Console.WriteLine("等待11秒缓存过期后再获取");
await Task.Delay(11000);
var dogResult3 = GetCacheData("泰迪");
Console.WriteLine($"查询结果3:{dogResult3}");
//向缓存中添加泰迪
SetCacheData(new Dog("泰迪", 1), cacheOptions);
var dogResult4 = GetCacheData("泰迪");
Console.WriteLine($"查询结果4:{dogResult4}");
var dogResult5 = GetCacheData("吉娃娃");
Console.WriteLine($"查询结果5:{dogResult5}");
} /// <summary>
/// 从缓存中获取数据
/// 如果没有则从数据源获取并添加至缓存
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private static async Task<Dog> GetDogAsync(string name)
{
//从容器中获取缓存服务
IMemoryCache memoryCache = host.Services.GetRequiredService<IMemoryCache>();
//查询缓存数据,没有则从数据源查询并添加至缓存
var dogResult = await memoryCache.GetOrCreateAsync(name, t =>
{
t.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(10);
Console.WriteLine($"缓存中没有{name},查询集合数据!");
Dog dog1 = dogs.SingleOrDefault(d => d.Name.Equals(name));
return Task.FromResult(dog1);
});
return dogResult;
} /// <summary>
/// 向缓存中添加数据
/// </summary>
/// <param name="dog"></param>
/// <param name="options"></param>
private static void SetCacheData(Dog dog, MemoryCacheEntryOptions options)
{
//从容器中获取缓存服务
IMemoryCache memoryCache = host.Services.GetRequiredService<IMemoryCache>();
memoryCache.Set(dog.Name, dog, options);
} /// <summary>
/// 缓存中获取数据
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
private static Dog GetCacheData(string key)
{
//从容器中获取缓存服务
IMemoryCache memoryCache = host.Services.GetRequiredService<IMemoryCache>();
return memoryCache.Get<Dog>(key);
} /// <summary>
/// 获取所有可爱的狗
/// </summary>
/// <returns></returns>
private static IEnumerable<Dog> GetDogs()
{
yield return new Dog("泰迪", 1);
yield return new Dog("吉娃娃", 2);
yield return new Dog("哈士奇", 3);
yield return new Dog("罗威纳", 4);
}
}
/// <summary>
/// 狗类
/// </summary>
/// <param name="Name"></param>
/// <param name="Id"></param>
internal record Dog(string Name, int Id);

输出结果:

缓存中没有泰迪,查询集合数据!
查询结果1:Dog { Name = 泰迪, Id=1 }
缓存中没有吉娃娃,查询集合数据!
香询结果1:Dog { Name = 告娃娃, Id=2 }
缓存中没有哈士奇,查询集合数据!
查询结果1:Dog { Name = 哈士奇, Id=3 }
缓存中没有罗威纳,查询集合数据!
香询结果1:Dog { Name = 罗威纳, Id=4 }
查询结果2:Dog { Name = 泰迪, Id=1 }
等待11秒缓存过期后再获取
查询结果3:
查询结果4:Dog { Name = 泰迪, Id=1 }
查询结果5:

二、常见问题

1、缓存雪崩

是指同一时间大量缓存失效, 导致大量请求发向后端服务。向缓存添加数据时,时间可以设置一定范围的随机时间,这是一种避免出现缓存雪崩的简单方法。

2、缓存击穿

是指热点缓存失效,导致查询该热点数据的请求大量查询后端服务。如果业务场景允许,可以每次延长缓存时间或者设置为不过期。也可以使用单独的任务来维护热点数据缓存。

3、缓存穿透

是指大量不存在的数据请求(比如恶意请求)进行查询,此时缓存和后端服务中都没有这些数据,浪费大量资源。这个时候使用布隆过滤器是个很好的选择。

.Net Core MemoryCache 缓存的更多相关文章

  1. .NET Core MemoryCache缓存获取全部缓存键

    在Core中不能使用原HttpRuntime.Cache缓存,改为MemoryCache(Microsoft.Extensions.Caching.Memory). 现MemoryCache新版为2. ...

  2. 拥抱.NET Core系列:MemoryCache 缓存选项

    在上一篇 "拥抱.NET Core系列:MemoryCache 缓存过期" 中我们详细的了解了缓存过期相关的内容,今天我们来介绍一下 MSCache 中的 Options,由此来介 ...

  3. 拥抱.NET Core系列:MemoryCache 缓存域

    在上一篇“<拥抱.NET Core系列:MemoryCache 缓存选项>”我们介绍了一些 MSCache 的机制,今天我们来介绍一下 MSCache 中的缓存域. MSCache项目 M ...

  4. 拥抱.NET Core系列:MemoryCache 缓存域(转载)

    阅读目录 MSCache项目 缓存域 写在最后 在上一篇“<拥抱.NET Core系列:MemoryCache 缓存选项>”我们介绍了一些 MSCache 的机制,今天我们来介绍一下 MS ...

  5. 拥抱.NET Core系列:MemoryCache 缓存选项 (转载)

    阅读目录 MSCache项目 MemoryCacheOptions ExpirationScanFrequency SizeLimit CompactionPercentage 写在最后 在上一篇 ” ...

  6. Asp.Net Core 2.0 项目实战(8)Core下缓存操作、序列化操作、JSON操作等Helper集合类

    本文目录 1.  前沿 2.CacheHelper基于Microsoft.Extensions.Caching.Memory封装 3.XmlHelper快速操作xml文档 4.Serializatio ...

  7. 讨论过后而引发对EF 6.x和EF Core查询缓存的思考

    前言 最近将RabbitMQ正式封装引入到.NET Core 2.0项目当中,之前从未接触过是个高大上的东东跟着老大学习中,其中收获不少,本打算再看看RabbitMQ有时间写写,回来后和何镇汐大哥探讨 ...

  8. MemoryCache缓存 ---缓存时效

    MemoryCache缓存 ---缓存时效测试 var cachePool = new MyCachePool(); //Thread.Sleep(1000); var value = cachePo ...

  9. 拥抱.NET Core系列:MemoryCache 缓存过期

    在上一篇"拥抱.NET Core系列:MemoryCache 初识"中我们基本了解了缓存的添加.删除.获取,那么今天我们来看看缓存的过期机制.这里和上篇一样将把"Micr ...

  10. .NET Core 的缓存篇之MemoryCache

    前言 对于缓存我们都已经很熟悉了,缓存分为很多种,浏览器缓存.试图缓存.服务器缓存.数据库缓存等等一些,那今天我们先介绍一下视图缓存和MemoryCache内存缓存的概念和用法: 视图缓存 在老的版本 ...

随机推荐

  1. 解决 C# 连接oracle 读出中文乱码的问题

    一开始,我使用odbc连接oracle,发现中文变成了??,这种已经成了??的乱码是不能通过 Text.Encoding的方式来转码的. 1.我到处查资料,发现有说设置客户端 系统变量 把 远程服务器 ...

  2. .net C# System.Text.Json 如何将 string类型的“true”转换为布尔值 解决方案

    直接上解决方法的代码 先定义一个转换顺,代码如下: public sealed class AnhBoolConverter : JsonConverter<bool?> { public ...

  3. SQLServer如何监控阻塞会话

    一.查询阻塞和被阻塞的会话 SELECT r.session_id AS [Blocked Session ID], r.blocking_session_id AS [Blocking Sessio ...

  4. OceaBase 分区表创建技巧

    最近遇在干个核心的金融项目,规模很大,客户主要是用oracle数据库,现在需要适配ob,原来在oracle就是分区表的迁来ob以后需要进行改造. oracle默认使用是堆表(ht),而ob使用的是索引 ...

  5. Aspire项目发布到远程k8s集群

    前提 你必须会创建aspire项目,不会的请先看微服务新体验之Aspire初体验 Aspirate (Aspir8) Aspirate 是将aspire项目发布到k8s集群的工具 安装aspirate ...

  6. rhce练习题容易错的地方

    rhce练习题里容易错的地方 使用导航器的时候,ssh连接 因为导航器是一个工具,生成一个容器,在容器里面运行playbook 安装软件包的时候,多个软件包使用循环loop loop的格式 - hos ...

  7. Android应用程序启动流程浅析-(三万字长文慎点&Android14)

    在Android桌面Launcher源码浅析中介绍了Android的桌面程序Launcher是如何响应用户点击事件并启动App的,这篇文章继续介绍App在Android系统层是的启动流程. 一.启动流 ...

  8. 机器学习算法(一):1. numpy从零实现线性回归

    系列文章目录 机器学习算法(一):1. numpy从零实现线性回归 机器学习算法(一):2. 线性回归之多项式回归(特征选取) @ 目录 系列文章目录 前言 一.理论介绍 二.代码实现 1.导入库 2 ...

  9. NFS练习

    NFS练习题 1.开放/nfs/share目录,提供给 任意用户 只读(/etc/exports ro) 查询 1.任意客户端2.任意的用户​ 服务端 showmout exportfs system ...

  10. 请写出常用的linux指令

    a.cd /home 进入 '/ home' 目录' b.cd .. 返回上一级目录 c.cd ../.. 返回上两级目录 d.mkdir dir1 创建一个叫做 'dir1' 的目录' e.mkdi ...