C#怎么使用MemoryCache进行缓存 .NET内存缓存使用教程

来源:这里教程网 时间:2026-02-21 17:39:54 作者:

MemoryCache 是 .NET 内置的线程安全内存缓存组件,适用于单机应用中临时存储高频读、低频写的数据,比如配置项、字典表、API 响应结果等。它不依赖外部服务(如 Redis),开箱即用,但数据只存在于当前进程内存中,重启即丢失。

1. 引入命名空间并创建缓存实例

在 .NET 5+ 或 .NET Core 项目中,

Microsoft.Extensions.Caching.Memory
已内置,无需额外安装 NuGet 包(旧版 .NET Framework 需手动安装
Microsoft.Extensions.Caching.Memory
)。

推荐通过依赖注入使用缓存,而不是手动 new 实例 —— 这样能保证生命周期统一、线程安全且便于测试:

Program.cs
(.NET 6+)或
Startup.cs
中注册:

builder.Services.AddMemoryCache(); // 注册为单例服务
在类中通过构造函数注入
IMemoryCache
public class ProductService
{
    private readonly IMemoryCache _cache;
<pre class="brush:php;toolbar:false;">public ProductService(IMemoryCache cache)
{
    _cache = cache;
}

}

2. 存储与读取缓存项

MemoryCache 使用键值对方式操作,键必须是

object
类型(通常用 string),值任意类型。注意:键需全局唯一,建议加前缀避免冲突(如
"product:1001"
)。

写入缓存(带过期策略):
_cache.Set("product:1001", product, new MemoryCacheEntryOptions()
    .SetAbsoluteExpiration(TimeSpan.FromMinutes(30))           // 30 分钟后绝对过期
    .SetSlidingExpiration(TimeSpan.FromMinutes(10))          // 10 分钟内无访问则过期
    .SetPriority(CacheItemPriority.Normal)                    // 优先级,内存紧张时决定淘汰顺序
    .RegisterPostEvictionCallback((key, value, reason, state) =>
    {
        Console.WriteLine($"缓存 {key} 因 {reason} 被移除");
    }));
读取缓存(推荐用 TryGetValue,性能更好):
if (_cache.TryGetValue("product:1001", out Product? cachedProduct))
{
    return cachedProduct;
}
// 缓存未命中,查数据库并写入
var product = _db.Products.Find(id);
_cache.Set("product:1001", product, TimeSpan.FromMinutes(30));
return product;

3. 高级用法:自动刷新与弱引用场景

MemoryCache 不支持自动后台刷新(如定时重加载),但可通过封装 + 定时任务或“懒加载+滑动过期”模拟软刷新效果。

避免缓存击穿:用
GetOrCreate
原子操作,确保同一键只执行一次工厂方法:
return _cache.GetOrCreate("config:site", entry =>
{
    entry.SetAbsoluteExpiration(TimeSpan.FromMinutes(5));
    return LoadSiteConfigFromDb(); // 此方法只会被调用一次(并发下也只一次)
});
大对象注意:缓存大型对象(如大 byte[])可能引发 GC 压力,可考虑用
WeakReference
包装或改用文件/分布式缓存
清理缓存:调用
_cache.Remove("key")
_cache.Compact(percentage: 50)
主动释放约 50% 占用空间(按优先级和过期时间估算)

4. 注意事项与常见坑

缓存键不能为 null,否则抛异常;建议用
nameof
+ ID 组合生成键
不要缓存 DbContext 实例、HttpContext、Controller 等有生命周期的对象 —— 会引发内存泄漏或异常 默认最大缓存大小不限,但内存不足时会自动逐出(基于优先级+过期时间);如需硬性限制,可设置
SizeLimit
并配合
Size
选项
在单元测试中,可用
new MemoryCache(new MemoryCacheOptions())
创建轻量实例,无需 DI 容器

基本上就这些。MemoryCache 上手简单,关键在于合理设过期策略、避免缓存污染、不滥用大对象 —— 控制好这几点,日常业务缓存需求基本都能稳稳覆盖。

相关推荐