Question

Je l'ai créé mon propre gestionnaire de cache pour un site web que je développe et je cherchais à trouver la meilleure façon de vider le cache dans certaines circonstances.

J'ai trouvé de nombreux articles disant la bonne façon de vider le cache est d'appeler HttpRuntime.Close ()

Cependant, dans mes tests unitaires configuration que j'appelle la fonction encapsulée HttpRuntime.Close () et le cache est d'être vidé.

Je m'y attendais à réaliser quelque chose de similaire à

foreach (DictionaryEntry cacheItem in HttpRuntime.Cache)
{
    HttpRuntime.Cache.Remove(cacheItem.Key.ToString());
}

La boucle foreach fonctionne très bien dans ma fonction encapsulée, mais Close () ne fonctionne jamais droit.

Suis-je mal compris le but de HttpRuntime.Close () ou est-il quelque chose de plus sinistre se passe ici?

Était-ce utile?

La solution

Ne pas utiliser Close, il fait plus que les docs disent. Et les docs disent aussi ne pas l'utiliser lors du traitement des demandes normales ...

est la source réfléchie de fermeture ():

[SecurityPermission(SecurityAction.Demand, Unrestricted=true)]
public static void Close() {
    if (_theRuntime.InitiateShutdownOnce()) {
        SetShutdownReason(ApplicationShutdownReason.HttpRuntimeClose, "HttpRuntime.Close is called");
        if (HostingEnvironment.IsHosted) {
            HostingEnvironment.InitiateShutdown();
        } else {
            _theRuntime.Dispose();
        }
    }
}

En outre, vous ne pouvez pas itérer sur une collection et supprimer des éléments de en même temps, car cela rend l'énumération non valide.

Alors, essayez ce lieu, qui ne change pas ce qu'il passe en boucle sur:

List<string> toRemove = new List<string>();
foreach (DictionaryEntry cacheItem in HttpRuntime.Cache) {
    toRemove.Add(cacheItem.Key.ToString());
}
foreach (string key in toRemove) {
    HttpRuntime.Cache.Remove(key);
}

Cela dit, vraiment, vous devriez essayer d'utiliser des dépendances de cache pour avoir les entrées de cache non valides efface automatiquement pour vous, et tout cela devient inutile.

Autres conseils

  
    

Je comprends la question avec l'énumération, mais pour une raison quelconque le cache ne semble pas avoir un problème suppression d'un élément en marchant dans la liste.

  

Si vous percez jusqu'à la mise en œuvre du détail, vous trouverez le recenseur est créé par CacheSingle.CreateEnumerator, une nouvelle instance Hashtable est créée pour le dénombrement.

C'est pourquoi vous pouvez faire la supprimer dans une boucle foreach.

vous pouvez simplement mettre en œuvre votre propre classe de cache, vérifiez le ci-dessous un:

 public sealed class YourCache<T>
{
    private Dictionary<string, T> _dictionary = new Dictionary<string, T>();

    private YourCache()
    {
    }

    public static YourCache<T> Current
    {
        get
        {
            string key = "YourCache|" + typeof(T).FullName;
            YourCache<T> current = HttpContext.Current.Cache[key] as YourCache<T>;
            if (current == null)
            {
                current = new YourCache<T>();
                HttpContext.Current.Cache[key] = current;
            }
            return current;
        }
    }

    public T Get(string key, T defaultValue)
    {
        if (string.IsNullOrWhiteSpace(key))
            throw new ArgumentNullException("key should not be NULL");

        T value;
        if (_dictionary.TryGetValue(key, out value))
            return value;

        return defaultValue;
    }

    public void Set(string key, T value)
    {
        if (key == null)
            throw new ArgumentNullException("key");

        _dictionary[key] = value;
    }

    public void Clear()
    {
        _dictionary.Clear();
    }
}

vous pouvez appeler les éléments du cache ou même les effacer en utilisant les éléments suivants:

 // put something in this intermediate cache
YourCache<ClassObject>.Current.Set("myKey", myObj);

// clear this cache
YourCache<ClassObject>.Current.Clear();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top