如何遍历 asp.net 内核中的 MemoryCache?
How to iterate through MemoryCache in 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);
}
}
https://github.com/aspnet/Caching/blob/dev/src/Microsoft.Extensions.Caching.Memory/MemoryCache.cs
您应该缓存两种类型的项目。
- 您按原样缓存您的属性,
abc.xyz-{0}
。
- 第二次缓存主键名下属性的列表,
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));
删除时:
var keys = cache.Get<List<string>>("abc.xyz");
foreach(var key in keys)
cache.Remove(key);
cache.remove("abc.xyz");
大多数服务使用 IDistributedCache
(在您的情况下,注册时 MemoryDistributedCache
- 再次注入 IMemoryCache
,即 MemoryCache
class)。
在分布式缓存中,您无法遍历所有键,因为可能有数百万个键,如果您 could/would 遍历它,这将显着降低缓存服务的性能。
因此,当您将内存缓存替换为分布式缓存(例如Redis)时,上述解决方案也很友好并且可以准备就绪。
对于大型项目,这是一种有点尴尬的方式。我建议您使用包装器 class 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
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);
}
}
https://github.com/aspnet/Caching/blob/dev/src/Microsoft.Extensions.Caching.Memory/MemoryCache.cs
您应该缓存两种类型的项目。
- 您按原样缓存您的属性,
abc.xyz-{0}
。 - 第二次缓存主键名下属性的列表,
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));
删除时:
var keys = cache.Get<List<string>>("abc.xyz");
foreach(var key in keys)
cache.Remove(key);
cache.remove("abc.xyz");
大多数服务使用 IDistributedCache
(在您的情况下,注册时 MemoryDistributedCache
- 再次注入 IMemoryCache
,即 MemoryCache
class)。
在分布式缓存中,您无法遍历所有键,因为可能有数百万个键,如果您 could/would 遍历它,这将显着降低缓存服务的性能。
因此,当您将内存缓存替换为分布式缓存(例如Redis)时,上述解决方案也很友好并且可以准备就绪。
对于大型项目,这是一种有点尴尬的方式。我建议您使用包装器 class 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