2009-04-29 6 views
3

Je Dépendances veux un élément de cache ASP.NET à recycler est touché quand un fichier spécifique, mais le code suivant ne fonctionne pas:ASP.NET Cache et fichier

     HttpContext.Current.Cache.Insert(
          "Key", 
          SomeObject, 
          new CacheDependency(Server.MapPath("SomeFile.txt")), 
          DateTime.MaxValue, 
          TimeSpan.Zero, 
          CacheItemPriority.High, 
          null); 

« Somefile.txt » ne semblent être vérifiés lorsque je touche le cache, et le modifier ne provoque pas l'invalidation de cet élément.

Qu'est-ce que je fais mal?

+0

Qu'est-ce que ObjectFile? Un string? –

+0

J'ai modifié pour le rendre plus évident. – FlySwat

Répondre

5

Problème résolu:

Ce fut un problème unique et intéressant, donc je vais documenter la cause et la solution ici comme une réponse, pour les chercheurs futurs. Quelque chose que j'ai omis dans ma question était que cette insertion de cache se produisait dans une classe de service implémentant le modèle singleton.

En bref:

public class Service 
{ 
     private static readonly Service _Instance = new Service(); 
     static Service() { } 
     private Service() { } 

     public static Service Instance 
     { 
      get { return _Instance; } 
     } 

     // The expensive data that this service exposes  
     private someObject _data = null; 

     public someObject Data 
     { 
      get 
      { 
       if (_data == null) 
        loadData(); 
       return _data; 
      } 
     } 


     private void loadData() 
     { 
      _data = GetFromCache(); 
      if (_data == null) 
      { 
       // Get the data from our datasource 
       _data = ExpensiveDataSourceGet(); 

       // Insert into Cache 
       HttpContext.Current.Cache.Insert(etc); 
      } 
     } 
} 

Il est peut-être évident pour certains, mais le coupable est ici le chargement à l'intérieur du motif singleton. J'étais tellement pris au dépourvu que le cache n'était pas invalidé, que j'avais oublié que l'état du singleton serait conservé aussi longtemps que le processus de travail serait en vie. Cache.Insert a une surcharge qui vous permet de spécifier un gestionnaire d'événements pour quand l'élément de cache est supprimé, mon premier test était de créer un gestionnaire fictif et de définir un point d'arrêt en son sein. Une fois que j'ai vu que le cache était en train d'être effacé, j'ai réalisé que "_data" n'était pas réinitialisé à null, donc la prochaine requête au singleton a chargé la valeur chargée paresseuse. Dans un sens, j'étais en double caching, bien que le cache singleton ait été de très courte durée, mais assez long pour être agaçant.

La solution?Lorsque le cache est effacé, l'état dans le singleton doit également être effacé ... problème résolu.

Leçon apprise ici? Ne mettez pas l'état dans un singleton.

+0

merci de partager que c'est une mauvaise pratique de garder l'état dans votre singleton – JJS

0

Je pense que vous aurez besoin de spécifier un chemin:

var d = new CacheDependency(Server.MapPath("SomeFile.txt")); 

avec ~\App_Data Prepend au besoin.

+0

Je passe déjà un chemin complet, désolé l'exemple artificiel n'était pas clair. – FlySwat

0

Votre code me semble bien. Cependant, au-delà de cet extrait, tout pourrait se passer.

  • Est-ce que vous réinsérez sur chaque publication par hasard? Essayez de faire de votre dépendance de cache un champ de classe et de le vérifier à chaque publication. Modifier le fichier entre et voir si elle enregistre jamais comme "Modifié". .: par exemple

    public partial class _Default : System.Web.UI.Page 
    { 
        CacheDependency dep; 
    
    protected void Page_Load(object sender, EventArgs e) 
    { 
        if (!IsPostBack) 
        { 
         dep = new CacheDependency(Server.MapPath("SomeFile.txt")); 
         HttpContext.Current.Cache.Insert(
            "Key", 
            new Object(), 
            dep, 
            DateTime.MaxValue, 
             TimeSpan.Zero, CacheItemPriority.High, null); 
        } 
    
    
        if (dep.HasChanged) 
         Response.Write("changed!"); 
        else 
         Response.Write("no change :("); }} 
    

+0

Ne pas réinsérer définitivement sur la publication. Ceci est réellement abstraite très loin dans une bibliothèque. – FlySwat

1

ASP.NET est en cours d'exécution sous un compte avec les autorisations appropriées pour le fichier spécifié dans le CacheDependency? Si ce n'est pas le cas, cela peut expliquer pourquoi CacheDependency ne fonctionne pas correctement.

+0

Oui, car il analyse ce fichier pour créer l'objet en cache d'origine. – FlySwat

0

La seule façon que je suis capable de reproduire ce comportement est si le chemin fourni au constructeur de CacheDependency n'existe pas. CacheDependency ne lèvera pas d'exception si le chemin n'existe pas, donc cela peut être un peu trompeur.

+0

Cependant, j'ouvre ce fichier (et j'utilise la même variable de chemin exacte) d'une ligne et le lit dans l'objet de cache. – FlySwat

Questions connexes