Asp.net-Core
ASP.NET Core 從 IMemoryCache 清除記憶體(由 CacheExtensions 類的 Set 方法設置)
乍一看,這看起來與這個問題重複,但我不是在問如何清除 EF 的記憶體。
如何清除
IMemoryCache介面設置的整個記憶體?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; }這只是一個例子。我有許多將值儲存到記憶體的類/方法。現在我需要將它們全部刪除。
在某些情況下,我的密鑰是動態創建的,所以我不知道需要刪除哪些密鑰。清除將是完美的。
我可以編寫自己的內部使用的介面和類
IMemoryCache,但這似乎有點矯枉過正。有沒有更簡單的選擇?
因為我找不到任何好的解決方案,所以我自己編寫。
在 SamiAl90 解決方案(答案)中,我錯過了ICacheEntry介面中的所有屬性。
它在內部使用IMemoryCache。
案例與 2 個附加功能完全相同:
- 從記憶體記憶體中清除所有項目
- 遍歷所有鍵/值對
您必須註冊單身人士:
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; } }