乍一看,这看起来与这个问题重复,但我不是在问如何清除 EF 的缓存.
On first look this looks duplicate of this question, but I am not asking how to clear cache for EF.
如何清除IMemoryCache接口设置的整个缓存?
How can I clear entire cache set by IMemoryCache interface?
public CacheService(IMemoryCache memoryCache) { this._memoryCache = memoryCache; } public async Task<List<string>> GetCacheItem() { if (!this._memoryCache.TryGetValue("Something", out List<string> list)) { list= await this ... this._memoryCache.Set("Something", list, new MemoryCacheEntryOptions().SetPriority(CacheItemPriority.NeverRemove)); } return list; }这只是一个例子.我有许多类/方法存储要缓存的值.现在我需要将它们全部删除.
This is just an example. I have many classes/methods that are storing values to cache. Now I need to remove them all.
在某些情况下,我的密钥是动态创建的,因此我不知道需要删除哪些密钥.清晰就完美了.
My keys are, in some cases, created dynamically, so I don't know which keys I need to remove. Clear would be perfect.
我可以编写自己的接口和类,这些接口和类将在内部使用 IMemoryCache,但这似乎有点矫枉过正.有没有更简单的选择?
I could write my own interface and class which would internally use IMemoryCache, but this seems overkill. Is there any easier options?
推荐答案因为我找不到任何好的解决方案,所以我自己编写.在 SamiAl90 解决方案(答案)中,我错过了 ICacheEntry 接口.
Because I couldn't found any good solution I write my own. In SamiAl90 solution (answer) I missed all properties from ICacheEntry interface.
在内部使用 IMemoryCache.用例与 2 个附加功能完全相同:
Internally it uses IMemoryCache. Use case is exactly the same with 2 additional features:
你必须注册单身:
serviceCollection.AddSingleton<IMyCache, MyMemoryCache>();用例:
public MyController(IMyCache cache) { this._cache = cache; } [HttpPut] public IActionResult ClearCache() { this._cache.Clear(); return new JsonResult(true); } [HttpGet] public IActionResult ListCache() { var result = this._cache.Select(t => new { Key = t.Key, Value = t.Value }).ToArray(); return new JsonResult(result); }来源:
public interface IMyCache : IEnumerable<KeyValuePair<object, object>>, IMemoryCache { /// <summary> /// Clears all cache entries. /// </summary> void Clear(); } public class MyMemoryCache : IMyCache { private readonly IMemoryCache _memoryCache; private readonly ConcurrentDictionary<object, ICacheEntry> _cacheEntries = new ConcurrentDictionary<object, ICacheEntry>(); public MyMemoryCache(IMemoryCache memoryCache) { this._memoryCache = memoryCache; } public void Dispose() { this._memoryCache.Dispose(); } private void PostEvictionCallback(object key, object value, EvictionReason reason, object state) { if (reason != EvictionReason.Replaced) this._cacheEntries.TryRemove(key, out var _); } /// <inheritdoc cref="IMemoryCache.TryGetValue"/> public bool TryGetValue(object key, out object value) { return this._memoryCache.TryGetValue(key, out value); } /// <summary> /// Create or overwrite an entry in the cache and add key to Dictionary. /// </summary> /// <param name="key">An object identifying the entry.</param> /// <returns>The newly created <see cref="T:Microsoft.Extensions.Caching.Memory.ICacheEntry" /> instance.</returns> public ICacheEntry CreateEntry(object key) { var entry = this._memoryCache.CreateEntry(key); entry.RegisterPostEvictionCallback(this.PostEvictionCallback); this._cacheEntries.AddOrUpdate(key, entry, (o, cacheEntry) => { cacheEntry.Value = entry; return cacheEntry; }); return entry; } /// <inheritdoc cref="IMemoryCache.Remove"/> public void Remove(object key) { this._memoryCache.Remove(key); } /// <inheritdoc cref="IMyCache.Clear"/> public void Clear() { foreach (var cacheEntry in this._cacheEntries.Keys.ToList()) this._memoryCache.Remove(cacheEntry); } public IEnumerator<KeyValuePair<object, object>> GetEnumerator() { return this._cacheEntries.Select(pair => new KeyValuePair<object, object>(pair.Key, pair.Value.Value)).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } /// <summary> /// Gets keys of all items in MemoryCache. /// </summary> public IEnumerator<object> Keys => this._cacheEntries.Keys.GetEnumerator(); } public static class MyMemoryCacheExtensions { public static T Set<T>(this IMyCache cache, object key, T value) { var entry = cache.CreateEntry(key); entry.Value = value; entry.Dispose(); return value; } public static T Set<T>(this IMyCache cache, object key, T value, CacheItemPriority priority) { var entry = cache.CreateEntry(key); entry.Priority = priority; entry.Value = value; entry.Dispose(); return value; } public static T Set<T>(this IMyCache cache, object key, T value, DateTimeOffset absoluteExpiration) { var entry = cache.CreateEntry(key); entry.AbsoluteExpiration = absoluteExpiration; entry.Value = value; entry.Dispose(); return value; } public static T Set<T>(this IMyCache cache, object key, T value, TimeSpan absoluteExpirationRelativeToNow) { var entry = cache.CreateEntry(key); entry.AbsoluteExpirationRelativeToNow = absoluteExpirationRelativeToNow; entry.Value = value; entry.Dispose(); return value; } public static T Set<T>(this IMyCache cache, object key, T value, MemoryCacheEntryOptions options) { using (var entry = cache.CreateEntry(key)) { if (options != null) entry.SetOptions(options); entry.Value = value; } return value; } public static TItem GetOrCreate<TItem>(this IMyCache cache, object key, Func<ICacheEntry, TItem> factory) { if (!cache.TryGetValue(key, out var result)) { var entry = cache.CreateEntry(key); result = factory(entry); entry.SetValue(result); entry.Dispose(); } return (TItem)result; } public static async Task<TItem> GetOrCreateAsync<TItem>(this IMyCache cache, object key, Func<ICacheEntry, Task<TItem>> factory) { if (!cache.TryGetValue(key, out object result)) { var entry = cache.CreateEntry(key); result = await factory(entry); entry.SetValue(result); entry.Dispose(); } return (TItem)result; } }更多推荐
ASP.NET Core 从 IMemoryCache 清除缓存(由 CacheExtensions 类的 Set 方法设置)
发布评论