.NET Core MemoryCache存值后无法读取及单例ActionFilter性能咨询
问题排查与解答
一、缓存写入后无法读取的可能原因及排查步骤
1. 检查token的一致性
这是最常见的问题根源:两次请求的token看似相同,但实际存在差异。比如:
- 大小写不一致(如第一次是
abc123,第二次是ABC123) - 包含前后空格或不可见控制字符
token生成逻辑错误,比如每次请求都生成新值(错误将请求ID等动态内容加入token)- 若
token是自定义对象而非字符串,默认会以引用作为键,即使内容相同,不同实例也会被视为不同键
验证方式:在读取、设置缓存时,分别打印token的具体值(包括类型、哈希码、完整字符串),确认两次请求的token完全一致。
2. 检查缓存过期时间配置
确认_expirationMinutes的取值是否合理:
- 如果
_expirationMinutes设为0,缓存会立即过期,虽然设置成功,但下一次请求时条目已失效(MemoryCache的后台清理有延迟,所以缓存计数仍会显示存在) - 可以临时将过期时间改为固定值(如
TimeSpan.FromMinutes(5)),测试是否能正常读取
3. 确认缓存值的类型匹配
你读取缓存时用的是out int temp,需确认response.Score的类型确实是int。如果是long等其他数值类型,TryGetValue会因类型不匹配返回false,导致读取失败。
4. 验证MemoryCache实例一致性
虽然AddMemoryCache默认注册的是单例,但可以额外验证:在设置和读取缓存时,打印_cache的哈希码,确认是同一个实例(这一步大概率没问题,但可以排除极端情况)。
二、单例ActionFilter在低并发场景下的性能影响
每秒最多5次请求属于极低并发场景,使用单例ActionFilter不会有性能问题,反而有优势:
- 单例模式避免了每次请求创建Filter实例的开销,减少内存分配和GC压力
- 你注入的
IServiceScopeFactory、IMemoryCache本身都是线程安全的服务,不存在线程安全风险 - 低并发下完全不用担心资源竞争或性能瓶颈
附:你的代码整理
Program.cs
builder.Services.AddSingleton<MyActionFilter>(); builder.Services.AddMemoryCache();
MyActionFilter核心代码
public class MyActionFilter : ActionFilterAttribute { private readonly IServiceScopeFactory _serviceScopeFactory; private readonly IMemoryCache _cache; public MyActionFilter(IServiceScopeFactory serviceScopeFactory, IMemoryCache cache) { _serviceScopeFactory = serviceScopeFactory; _cache = cache; } // 读取缓存逻辑 if (_cache.TryGetValue(token, out int temp)) { await next.Invoke(); return; } // 设置缓存逻辑 if (response.Success) { if (response.Score >= _minimumAllowedScore) { _cache.Set(token, response.Score, new TimeSpan(0, _expirationMinutes, 0)); await next.Invoke(); return; } } }
内容的提问来源于stack exchange,提问作者Jamil
相关产品推荐
相关产品推荐

