Je peux trouver une méthode remove
pour supprimer un objet de IMemoryCache
par sa clé. Existe-t-il un moyen de réinitialiser l'ensemble du cache et de supprimer tous les objets?
Éditer:
Comment effacer MemoryCache? La méthode Dispose fournie dans le lien me donne une exception dans asp.net 5. ObjectDisposedException: Cannot access a disposed object. Object name: 'Microsoft.Extensions.Caching.Memory.MemoryCache'.
https://docs.Microsoft.com/en-us/aspnet/core/performance/caching/memory Section Dépendances du cache
L'utilisation d'un CancellationTokenSource permet d'expulser plusieurs entrées de cache en tant que groupe
Ce code a fonctionné pour moi:
public class CacheProvider
{
private static CancellationTokenSource _resetCacheToken = new CancellationTokenSource();
private readonly IMemoryCache _innerCache;
/* other methods and constructor removed for brevity */
public T Set<T>(object key, T value)
{
/* some other code removed for brevity */
var options = new MemoryCacheEntryOptions().SetPriority(CacheItemPriority.Normal).SetAbsoluteExpiration(typeExpiration);
options.AddExpirationToken(new CancellationChangeToken(_resetCacheToken.Token));
_innerCache.Set(CreateKey(type, key), value, options);
return value;
}
public void Reset()
{
if (_resetCacheToken != null && !_resetCacheToken.IsCancellationRequested && _resetCacheToken.Token.CanBeCanceled)
{
_resetCacheToken.Cancel();
_resetCacheToken.Dispose();
}
_resetCacheToken = new CancellationTokenSource();
}
}
Il y a beaucoup de hacks pour le faire. Si vous avez le bon IMemoryCache, vous pouvez utiliser Compact(1.0)
, sinon ce hack fonctionne:
Ce code fonctionnera (testé dans des tests unitaires et en production sur .NET core 2.2):
PropertyInfo prop = cache.GetType().GetProperty("EntriesCollection", BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Public);
object innerCache = prop.GetValue(cache);
MethodInfo clearMethod = innerCache.GetType().GetMethod("Clear", BindingFlags.Instance | BindingFlags.Public);
clearMethod.Invoke(innerCache, null);
La réponse à partir de RC1 est que vous ne pouvez pas le faire hors de la boîte à partir de ce que j'ai lu et qui m'a été dit (j'ai lu sur GitHub qu'il y avait peut-être un moyen de créer des déclencheurs pour faciliter cela à venir).
Actuellement, vous obtenez Get, Set et Remove. Je vois vos options comme:
https://github.com/blakepell/Caching/commit/165ae5ec13cc51c44a6007d6b88bd9c567e1d724
J'ai publié ce problème hier soir en essayant de déterminer s'il existe un bon moyen d'inspecter spécifiquement ce qui se trouve dans le cache (en demandant pourquoi nous n'avons pas de moyen de le faire). Si vous ne demandez pas, vous ne saurez jamais si cela aurait été important, alors j'ai pensé pourquoi pas.
Ma solution a été de créer un wrapper qui réexpose quelques méthodes existantes et d'ajouter une méthode manquante en remplaçant l'objet MemoryCache par un tout nouveau. A très bien fonctionné pour moi. Le code est ci-dessous:
public interface IMyMemoryCache : IMemoryCache
{
void Reset();
}
public class MyMemoryCache: IMyMemoryCache
{
IMemoryCache _memoryCache;
public MyMemoryCache()
{
Reset();
}
public void Dispose()
{
_memoryCache.Dispose();
}
public bool TryGetValue(object key, out object value)
{
return _memoryCache.TryGetValue(key, out value);
}
public ICacheEntry CreateEntry(object key)
{
return _memoryCache.CreateEntry(key);
}
public void Remove(object key)
{
_memoryCache.Remove(key);
}
public void Reset()
{
_memoryCache = new MemoryCache(new MemoryCacheOptions());
}
}
ma solution a été de définir une nouvelle date d'expiration pour tous les éléments du cache à 1 milliseconde. Ensuite, ils ont expiré et, par conséquent, le vidage du cache.
Ce code peut vous aider si vous utilisez le MemoryCache standard. Documentation: https://docs.Microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-3.1#memorycachecompact
_cache.Compact(1.0);