在.NET应用开发中,合理使用内存缓存能够显著降低重复计算或数据库查询的开销,提升系统整体性能。MemoryCache是.NET框架提供的原生内存缓存实现,适用于单机应用或分布式场景中不需要跨进程共享缓存的场景,使用起来简单且轻量。

MemoryCache基础概念
MemoryCache是.NET Core及后续版本中内置的缓存组件,位于Microsoft.Extensions.Caching.Memory命名空间下,核心接口是IMemoryCache。它支持设置缓存过期时间、缓存优先级、缓存移除回调等能力,能够满足大部分基础缓存需求。
环境准备与依赖引入
如果是.NET Core 3.1及以上版本的项目,默认已经包含了MemoryCache的相关依赖,不需要额外安装NuGet包。如果是较老版本的项目,需要安装Microsoft.Extensions.Caching.Memory包。
在ASP.NET Core项目中,需要在Program.cs中注册MemoryCache服务,代码如下:
// Program.cs 中注册服务 var builder = WebApplication.CreateBuilder(args); // 添加MemoryCache服务到依赖注入容器 builder.Services.AddMemoryCache(); var app = builder.Build();
基础缓存操作
写入缓存
注入IMemoryCache接口后,可以通过Set方法写入缓存,支持设置缓存的过期时间。以下是写入缓存的示例代码:
using Microsoft.Extensions.Caching.Memory;
public class UserService
{
private readonly IMemoryCache _memoryCache;
// 通过构造函数注入IMemoryCache
public UserService(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
public void SetCacheDemo()
{
string cacheKey = "user_info_1001";
var userInfo = new { Id = 1001, Name = "张三", Age = 25 };
// 写入缓存,设置绝对过期时间为10分钟
_memoryCache.Set(cacheKey, userInfo, TimeSpan.FromMinutes(10));
}
}
读取缓存
读取缓存可以使用Get方法,也可以通过TryGetValue方法判断缓存是否存在,避免直接读取时缓存不存在返回默认值的问题。示例代码如下:
public class UserService
{
private readonly IMemoryCache _memoryCache;
public UserService(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
public object GetCacheDemo()
{
string cacheKey = "user_info_1001";
// 方式1:直接Get读取,缓存不存在返回null
var data1 = _memoryCache.Get<object>(cacheKey);
// 方式2:TryGetValue判断是否存在,更安全
if (_memoryCache.TryGetValue(cacheKey, out object data2))
{
return data2;
}
return null;
}
}
移除缓存
当缓存数据失效或需要主动清理时,可以使用Remove方法移除指定键的缓存。示例代码如下:
public class UserService
{
private readonly IMemoryCache _memoryCache;
public UserService(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
public void RemoveCacheDemo()
{
string cacheKey = "user_info_1001";
// 移除指定键的缓存
_memoryCache.Remove(cacheKey);
}
}
进阶缓存配置
设置缓存过期策略
MemoryCache支持两种过期策略,可以单独使用也可以组合使用:
- 绝对过期时间:缓存从写入开始,经过指定时间后必定过期,使用
AbsoluteExpirationRelativeToNow配置。 - 滑动过期时间:缓存在被访问时,过期时间会重新计算,如果超过指定时间没有被访问则过期,使用
SlidingExpiration配置。
组合使用的示例代码如下:
public void SetCacheWithExpiration()
{
string cacheKey = "config_data";
var config = new { Version = "1.0.0", EnableLog = true };
// 设置绝对过期30分钟,滑动过期10分钟
// 即最多缓存30分钟,10分钟内没有访问则过期
var cacheOptions = new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(TimeSpan.FromMinutes(30))
.SetSlidingExpiration(TimeSpan.FromMinutes(10));
_memoryCache.Set(cacheKey, config, cacheOptions);
}
缓存移除回调
可以在缓存项被移除时执行自定义逻辑,比如记录日志或者处理后续业务。示例代码如下:
public void SetCacheWithRemoveCallback()
{
string cacheKey = "temp_data";
var tempData = "临时数据内容";
var cacheOptions = new MemoryCacheEntryOptions();
// 注册缓存移除回调
cacheOptions.RegisterPostEvictionCallback((key, value, reason, state) =>
{
// reason表示缓存移除的原因,比如过期、手动移除等
Console.WriteLine($"缓存键{key}被移除,原因:{reason}");
});
_memoryCache.Set(cacheKey, tempData, cacheOptions);
}
缓存优先级
当内存不足时,MemoryCache会优先移除优先级低的缓存项,优先级分为Low、Normal、High、NeverRemove四个级别,默认是Normal。设置优先级的示例代码如下:
public void SetCacheWithPriority()
{
string cacheKey = "important_data";
var data = "重要业务数据";
var cacheOptions = new MemoryCacheEntryOptions()
.SetPriority(CacheItemPriority.High); // 设置高优先级
_memoryCache.Set(cacheKey, data, cacheOptions);
}
使用注意事项
- MemoryCache是进程内缓存,应用重启后缓存会全部清空,不适合需要持久化或跨进程共享的场景。
- 不要缓存过大的对象,避免占用过多内存导致应用性能下降。
- 缓存键要尽量唯一,避免不同业务缓存键冲突覆盖数据。
- 如果业务需要缓存依赖,比如某个配置更新后清除相关缓存,需要手动实现缓存依赖逻辑,MemoryCache本身不提供原生的缓存依赖能力。
完整使用示例
以下是一个完整的查询用户信息的示例,优先从缓存读取,缓存不存在则查询数据库并写入缓存:
public class UserService
{
private readonly IMemoryCache _memoryCache;
private readonly DatabaseContext _dbContext; // 假设的数据库上下文
public UserService(IMemoryCache memoryCache, DatabaseContext dbContext)
{
_memoryCache = memoryCache;
_dbContext = dbContext;
}
public async Task<User> GetUserAsync(int userId)
{
string cacheKey = $"user_{userId}";
// 尝试从缓存读取
if (_memoryCache.TryGetValue(cacheKey, out User cachedUser))
{
return cachedUser;
}
// 缓存不存在,查询数据库
var user = await _dbContext.Users.FirstOrDefaultAsync(u => u.Id == userId);
if (user != null)
{
// 写入缓存,设置滑动过期5分钟,绝对过期30分钟
var cacheOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromMinutes(5))
.SetAbsoluteExpiration(TimeSpan.FromMinutes(30));
_memoryCache.Set(cacheKey, user, cacheOptions);
}
return user;
}
}
MemoryCacheC#缓存IMemoryCache修改时间:2026-07-06 09:27:33