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

发布于:2025-07-19 ⋅ 阅读:(11) ⋅ 点赞:(0)

在 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

  • 如果不存在,返回 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.总结

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


网站公告

今日签到

点亮在社区的每一天
去签到