在 Web API 开发中,频繁访问数据库或第三方服务可能会带来性能瓶颈。为了提升接口响应速度并减轻后端压力,使用缓存是非常有效的优化手段。
本文将带你快速上手 ASP.NET Core 提供的内存缓存(IMemoryCache
),无需安装额外库,轻量、简单、适合中小项目
什么是 IMemoryCache?
IMemoryCache
是 ASP.NET Core 自带的缓存机制,使用服务器内存来存储数据对象,单机部署即可使用,无需 Redis 等中间件。
它非常适合以下场景:
中小型项目
单台服务器部署
临时性或短期缓存需求(如列表页缓存、字典表缓存)
一. 启用缓存服务
IMemoryCache
默认已包含在 ASP.NET Core 中,仅需在 Program.cs
注册:
builder.Services.AddMemoryCache();
二. 在 Controller 或 Service 中使用缓存
以下是一个简单的控制器示例,缓存产品列表 5 分钟:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
[ApiController]
[Route("api/[controller]")]
public class ProductController : ControllerBase
{
private readonly IMemoryCache _cache;
public ProductController(IMemoryCache cache)
{
_cache = cache;
}
[HttpGet("GetAll")]
public IActionResult GetAll()
{
const string cacheKey = "product_list";
// 尝试从缓存中读取
if (_cache.TryGetValue(cacheKey, out List<string> cachedProducts))
{
return Ok(new { fromCache = true, data = cachedProducts });
}
// 模拟从数据库读取数据
var productsFromDb = new List<string> { "Apple", "Banana", "Orange" };
// 设置缓存项(滑动过期 5 分钟)
var cacheOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromMinutes(5));
_cache.Set(cacheKey, productsFromDb, cacheOptions);
return Ok(new { fromCache = false, data = productsFromDb });
}
}
三. IMemoryCache接口
IMemoryCache接口是ASP.NET Core 中用于本地内存缓存的核心接口,位于命名空间Microsoft.Extensions.Caching.Memory
下。
它本质上是一个轻量级的、线程安全的键值对缓存容器,你可以通过它来存取缓存项,而不需要关心底层缓存机制的实现。
下面是对它各个成员的详细讲解:
1.bool TryGetValue(object key, out object? value)
(1) 用途
尝试从缓存中获取一个键对应的值。
(2) 用法
if (_memoryCache.TryGetValue("product_list", out var value))
{
// value 是 object 类型,通常你需要强制转换一下
var products = value as List<Product>;
}
(3) 说明
如果
key
存在于缓存中,则返回true
,并将其值赋给value
如果不存在,返回
false
,value
是null
2.ICacheEntry CreateEntry(object key)
(1) 用途
创建一个新的缓存项,或更新已有项。
(2) 用法(不常用,推荐用 .Set()
封装版本)
var entry = _memoryCache.CreateEntry("product_list");
entry.Value = new List<string> { "Apple", "Banana" };
entry.SlidingExpiration = TimeSpan.FromMinutes(5);
entry.Dispose(); // 必须手动 Dispose,否则不会生效!
注意:
CreateEntry()
返回的是一个ICacheEntry
,需要Dispose()
才能提交。通常你不需要直接用这个方法,而是使用更方便的Set()
方法(实际上它内部就是调用了这个方法并自动处理)。
3.void Remove(object key)
(1) 用途
显式移除某个缓存项。
(2) 用法
_memoryCache.Remove("product_list");
(3) 场景
数据更新时主动清除旧缓存
控制缓存大小
用户退出登录后清除用户相关缓存
4.MemoryCacheStatistics? GetCurrentStatistics()
(1) 用途
获取当前缓存的统计数据(如命中率、条目数等)。
(2) 用法
var stats = _memoryCache.GetCurrentStatistics();
if (stats != null)
{
Console.WriteLine($"Entries: {stats.CurrentEntryCount}, Hits: {stats.TotalHits}");
}
仅在启用了统计时才有意义,在默认
MemoryCacheOptions
下此功能为 关闭状态。
上述成员我们一般不会使用,donet有更高级的封装给我们使用!
5.常配套的扩展方法(推荐使用)
虽然 IMemoryCache
提供了上述原始 API,但大多数开发者会用这些 更方便的扩展方法(定义在 MemoryCacheExtensions
类中):
Set
方法(创建或更新)
_memoryCache.Set("product_list", data, TimeSpan.FromMinutes(5));
Get<T>
方法(读取)
var list = _memoryCache.Get<List<string>>("product_list");
GetOrCreate
方法(读取或创建)
这个方法是最推荐使用的,先尝试从缓存获取,如果缓存没有那么回调方法里面再从数据库里面查找,
如果数据库没有别忘了抛出异常,避免缓存null
var result = _memoryCache.GetOrCreate("product_list", entry =>
{
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5);
return GetProductsFromDb(); // 如果没缓存,就调用这个方法
});
6.总结
IMemoryCache
是 ASP.NET Core 中的本地缓存接口,提供最基本的存取能力(TryGetValue、CreateEntry、Remove)和可选统计功能(GetCurrentStatistics),但推荐使用其扩展方法Set
、Get
、GetOrCreate
来更高效地完成常规缓存需求。
四. 缓存策略说明
MemoryCacheEntryOptions
提供了多种配置方式:
方法 | 说明 |
---|---|
SetSlidingExpiration |
如果缓存一段时间内没被访问就自动过期 |
SetAbsoluteExpiration |
缓存数据在指定时间后无论如何都过期 |
SetPriority |
设置缓存项在清除时的优先级 |
RegisterPostEvictionCallback |
缓存被移除时触发回调函数 |
五. 使用注意事项
只适用于单机,如果你使用的是集群或容器化部署,请考虑分布式缓存(如 Redis)。
缓存 key 应该具有唯一性,避免与其他模块冲突。
不要缓存过大的数据,避免内存膨胀。
对于会频繁更新的数据,需做好缓存失效机制设计。
六. 建议:封装为服务层缓存逻辑
为避免控制器代码臃肿,推荐将缓存逻辑封装进服务类中,控制器只负责返回结果。
public class ProductService
{
private readonly IMemoryCache _cache;
public ProductService(IMemoryCache cache)
{
_cache = cache;
}
public List<string> GetAllProducts()
{
if (_cache.TryGetValue("product_list", out List<string> products))
return products;
var list = new List<string> { "Apple", "Banana", "Orange" };
_cache.Set("product_list", list, TimeSpan.FromMinutes(5));
return list;
}
}
七. 总结
优点 | 缺点 |
---|---|
快速、轻量 | 仅支持单节点 |
使用简单 | 数据丢失风险(如进程重启) |
零依赖 | 不适合大规模持久缓存 |
对于中小型的 Web API 项目,IMemoryCache
是一个非常合适的选择。在性能与复杂度之间取得平衡,能让你在几行代码内大幅提升响应速度!