如何在asp.net核心中迭代MemoryCache?

nam*_* vo 3 c# memorycache asp.net-core

IMemoryCache中没有可用的方法允许迭代每个缓存的项目.我的项目很小,我不想使用像Redis这样的其他选项.

namepsace    Microsoft.Extensions.Caching.Memory{
        public static class CacheExtensions
    {
        public static object Get(this IMemoryCache cache, object key);
        public static TItem Get<TItem>(this IMemoryCache cache, object key);
        public static TItem GetOrCreate<TItem>(this IMemoryCache cache, object key, Func<ICacheEntry, TItem> factory);
        [AsyncStateMachine(typeof(CacheExtensions.<GetOrCreateAsync>d__9<>))]
        public static Task<TItem> GetOrCreateAsync<TItem>(this IMemoryCache cache, object key, Func<ICacheEntry, Task<TItem>> factory);
        public static TItem Set<TItem>(this IMemoryCache cache, object key, TItem value);
        public static TItem Set<TItem>(this IMemoryCache cache, object key, TItem value, DateTimeOffset absoluteExpiration);
        public static TItem Set<TItem>(this IMemoryCache cache, object key, TItem value, TimeSpan absoluteExpirationRelativeToNow);
        public static TItem Set<TItem>(this IMemoryCache cache, object key, TItem value, IChangeToken expirationToken);
        public static TItem Set<TItem>(this IMemoryCache cache, object key, TItem value, MemoryCacheEntryOptions options);
        public static bool TryGetValue<TItem>(this IMemoryCache cache, object key, out TItem value);
    }
}
Run Code Online (Sandbox Code Playgroud)

https://github.com/aspnet/Caching/blob/dev/src/Microsoft.Extensions.Caching.Memory/MemoryCache.cs

Tse*_*eng 14

您应该缓存两种类型的项目.

  1. 您可以按原样缓存属性abc.xyz-{0}.
  2. 第二次缓存主键名称下的属性列表, abc.xyz

示例代码:

cache.Set("abc.xyz-name", name, TimeSpan.FromMinutes(30));
cache.Set("abc.xyz-lastname", lastname, TimeSpan.FromMinutes(30));
cache.Set("abc.xyz-birthday", birthday, TimeSpan.FromMinutes(30));
cache.Set("abc.xyz", new List<string> { "abc.xyz-name", "abc.xyz-lastname", "abc.xyz-birthday" }, TimeSpan.FromMinutes(30));
Run Code Online (Sandbox Code Playgroud)

并在删除时:

var keys = cache.Get<List<string>>("abc.xyz");
foreach(var key in keys)
    cache.Remove(key);
cache.remove("abc.xyz");
Run Code Online (Sandbox Code Playgroud)

大多数服务都使用IDistributedCache(在您MemoryDistributedCache注册的情况下- 再次注入IMemoryCache哪个MemoryCache类).

在分布式缓存中,您无法迭代所有密钥,因为可能存在数百万个密钥,如果您可以/将迭代它,这将显着降低缓存服务的性能.

因此,当您使用分布式缓存(例如Redis)替换内存缓存时,上述解决方案也非常友好.

  • 我想指出的是,除非实施了某种并发控制,否则这种解决方案不是并发证明的;考虑两个独立的执行流在同一个存储桶下添加一个新属性——这可能会导致属性被添加到缓存中,但存储桶丢失它的情况; (4认同)

Lap*_*mir 5

对于大型项目,这有点尴尬。我建议您使用包装类 MemoryCacheManager 并将其注册为 Singleton。https://gist.github.com/vlapenkov/0a66c40221f9c56d12eb0420fb7cef77

_manager.Get("key", ()=>"value") // to set a key,

_manager.GetKeys() // get all keys

_manager.Remove("key") //remove one key

_manager.Clear() //remove all keys
Run Code Online (Sandbox Code Playgroud)