ASP.NET Core Web API 内存缓存(IMemoryCache)入门指南

在 Web API 开发中,频繁访问数据库或第三方服务可能会带来性能瓶颈。为了提升接口响应速度并减轻后端压力,使用缓存是非常有效的优化手段

本文将带你快速上手 ASP.NET Core 提供的内存缓存(IMemoryCache),无需安装额外库,轻量、简单、适合中小项目


什么是 IMemoryCache?

IMemoryCacheASP.NET Core 自带的缓存机制,使用服务器内存来存储数据对象,单机部署即可使用,无需 Redis 等中间件

它非常适合以下场景:

  • 中小型项目

  • 单台服务器部署

  • 临时性或短期缓存需求(如列表页缓存、字典表缓存)


一. 启用缓存服务

IMemoryCache 默认已包含在 ASP.NET Core 中,仅需在 Program.cs 注册:

cs 复制代码
builder.Services.AddMemoryCache();

二. 在 Controller 或 Service 中使用缓存

以下是一个简单的控制器示例,缓存产品列表 5 分钟:

cs 复制代码
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

  • 如果不存在,返回 falsevaluenull


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.总结

IMemoryCacheASP.NET Core 中的本地缓存接口,提供最基本的存取能力(TryGetValue、CreateEntry、Remove)和可选统计功能(GetCurrentStatistics),但推荐使用其扩展方法 SetGetGetOrCreate 来更高效地完成常规缓存需求。


四. 缓存策略说明

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 是一个非常合适的选择。在性能与复杂度之间取得平衡,能让你在几行代码内大幅提升响应速度!

相关推荐
WZTTMoon17 小时前
Spring Boot 4.0 迁移核心注意点总结
java·spring boot·后端
寻kiki17 小时前
scala 函数类?
后端
疯狂的程序猴17 小时前
iOS App 混淆的真实世界指南,从构建到成品 IPA 的安全链路重塑
后端
bcbnb18 小时前
iOS 性能测试的工程化方法,构建从底层诊断到真机监控的多工具测试体系
后端
开心就好202518 小时前
iOS 上架 TestFlight 的真实流程复盘 从构建、上传到审核的团队协作方式
后端
小周在成长18 小时前
Java 泛型支持的类型
后端
aiopencode18 小时前
Charles 抓不到包怎么办?HTTPS 抓包失败、TCP 数据流异常与底层补抓方案全解析
后端
稚辉君.MCA_P8_Java18 小时前
Gemini永久会员 C++返回最长有效子串长度
开发语言·数据结构·c++·后端·算法
Penge66618 小时前
Redis-bgsave浅析
redis·后端
梁bk18 小时前
Redis 内存回收
数据库·redis·缓存