不要使IMemoryCache实现中的缓存项过期

时间:2018-07-30 08:10:14

标签: c# caching asp.net-core asp.net-core-2.0

由于IMemoryCache并未提供太多有关缓存项的信息,因此我想实现一些自定义功能,以便将有关项的某些数据保留在缓存中,例如keyAbsoluteExpiration属性等。

这是我对IMemoryCache的实现:

public class MemoryCacheService : IMemoryCache
{
    private readonly MemoryCache _memoryCache;
    private readonly List<CacheItemRelevantData> _allKeys;
    private readonly string AllKeys = "___All__Keys___";
    public MemoryCacheService()
    {
        _memoryCache = new MemoryCache(new MemoryCacheOptions());
        _allKeys = new List<CacheItemRelevantData>();
        _memoryCache.Set(AllKeys, _allKeys, new MemoryCacheEntryOptions
        {
            AbsoluteExpiration = DateTimeOffset.MaxValue
        });
    }

    public void Dispose()
    {
        _memoryCache.Dispose();
    }

    public bool TryGetValue(object key, out object value)
    {
        return _memoryCache.TryGetValue(key, out value);
    }

    public ICacheEntry CreateEntry(object key)
    {
        var entry = _memoryCache.CreateEntry(key);
        entry.RegisterPostEvictionCallback((o, v, reason, state) =>
        {
            if (reason.In(EvictionReason.Capacity, EvictionReason.Expired, EvictionReason.TokenExpired))
            {
                var item = _allKeys.FirstOrDefault(x => x.Key.ToString() == o.ToString());
                if (item != null)
                {
                    _allKeys.Remove(item);
                }
            }
        });
        if (!_allKeys.Select(x => x.Key).Contains(key))
        {
            _allKeys.Add(new CacheItemRelevantData
            {
                Key = entry.Key,
                AbsoluteExpiration = entry.AbsoluteExpiration,
                Priority = entry.Priority,
                AbsoluteExpirationRelativeToNow = entry.AbsoluteExpirationRelativeToNow,
                Size = entry.Size
            });
        }
        return entry;
    }

    public void Remove(object key)
    {
        var entry = _allKeys.FirstOrDefault(x => x.Key.ToString() == key.ToString());
        if (entry != null)
        {
            _allKeys.Remove(entry);
        }

        _memoryCache.Remove(key);
    }
}

但是由于创建了_allKeys来存储有关缓存项目的相关数据,所以我不希望它过期。

是否可以将过期时间设置为无或类似的设置,并且_allKeys列表将永远保留在缓存中?

1 个答案:

答案 0 :(得分:0)

对于我来说,我很容易解决问题,因为IMemoryService被配置为范围服务,这意味着_allKeys变量将在IMemoryService实例中持久存在(直到iis是重新启动等)。对于非范围服务,我没有找到合适的解决方案,但我认为IMemoryCache服务应始终是有范围的服务(没有实际情况可以对其进行不同的配置-也许!