IMemoryCache 为缓存值返回 False

IMemoryCache Returning False for Cached Value

我有一个配置为 Windows 服务的 .NET 6 应用程序,我试图利用 IMemoryCache 存储用于 API 交互的临时访问令牌。我在缓存中看到一些非常奇怪的行为,导致无法检索我刚刚在上一次执行中添加的值。

我有一个名为 ITokenCacheServiceIMemoryCache 的简单抽象,它是这样实现的:

public class TokenCacheService : ITokenCacheService
{
    private readonly IMemoryCache _cache;

    public TokenCacheService(IMemoryCache cache)
    {
        _cache = cache;
    }

    public bool TryGetToken(TokenScope scope, out string token)
    {
        return _cache.TryGetValue(scope, out token);
    }

    public void AddTokenToCache(TokenScope scope, string token, int expiresIn)
    {
        _cache.Set(scope, token, TimeSpan.FromTicks(expiresIn));
    }
}

此 class 的调用者首先尝试 TryGetToken() 使用缓存值,如果失败,它会联系 API 以获取新的访问令牌然后用 AddTokenToCache() 缓存它。这在第一次通过时效果很好,缓存预计为空,因此添加了令牌。但是,在第二次后台服务再次运行时,IMemoryCache 将无法检索刚刚放入缓存中的相同值。

调试这个过程,我实际上可以在调用TryGetValue之前在缓存中看到我之前缓存的值。即便如此,它 returns false 并且无法 return 缓存值。真正奇怪的地方 - 不仅 returning false 用于实际缓存的值,而且在 TryGetValue 执行后, 该值随后从cache,即使它在调用之前就存在。我用下面的方式修改了 TryGetToken 来测试这个:

public bool TryGetToken(TokenScope scope, out string token)
{
    // Casting to have access to .Count 
    var cacheImpl = (MemoryCache)_cache; 

    var countBefore = cacheImpl.Count; // Count here is 1

    var result = _cache.TryGetValue(scope, out token); // Result here is false

    var countAfter = cacheImpl.Count; // Count here is 0 ???

    return result;
}

可以如果我在设置后立即尝试检索它,我可以取出令牌。我通过修改 AddTokenToCache 来测试这个只是为了检查值:

public void AddTokenToCache(TokenScope scope, string token, int expiresIn)
{
    _cache.Set(scope, token, TimeSpan.FromTicks(expiresIn));

    // Success here will be 'true' and 'test' will contain the token value. 
    var success = _cache.TryGetValue(scope, out var test); 
}

为此令牌设置的刻度数为 31536000,即 18 天 6 小时。我不认为我即将到期 window。我使用内存缓存的默认注册方法,没有任何选项:

services.AddMemoryCache();

我是否期望此服务以其未设计的方式工作,或者我是否需要以某种我未采用的方式对其进行配置?真的不确定我在这里错过了什么。当我第二次返回时,该值显然存在于缓存中,但是 TryGetValue() 失败并且似乎正在 将其从缓存中删除

The number of ticks being set for this token is 31536000, which amounts to 18 days and 6 hours

31536000 个刻度约为 3.1 秒,这可能是您所看到的原因。 MemoryCache 只会在您与之交互时寻找要驱逐的条目。一旦您尝试查询您的条目就会消失,这一事实与该条目过期一致,并且 MemoryCache 只在那时注意到。

18 天 6 小时是惊人的 15768000000000 刻。