2011-03-14 4 views
0

J'ai implémenté la mise en cache asp.net. Mais je reçois des résultats bizarresASP.net Caching

Contrairement à la plupart des mises en cache où vous essayez d'éviter le nombre de visites à la base de données. J'essaye d'éviter n'importe quels coups à la DB par l'utilisateur. C'est la durée de chargement de la première page.

J'ai essayé plusieurs techniques 1) Avoir le temps de cache très long et avoir un processus de planification expire et obtenir un nouveau cache. 2) et sur RemoveCallback

Dans la deuxième option, tout le cache passe par une classe statique que j'ai créée. Le but est tel qu'il expire pour actualiser les données. Voici ce que j'appelle.

Cache.Insert(dbCacheString, dtNetwork, null, DateTime.Now.AddHours(2), 
    System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.High, 
    new CacheItemRemovedCallback(CacheManager.CacheRemovedCallback)); 

    public static class CacheManager 
    { 
     private static Hashtable times = new Hashtable(); 
     private static bool isRefreshingCache = false; 

     public static void CacheRemovedCallback(String key, object value, 
      CacheItemRemovedReason removedReason) 
     { 
      RefreshCache(key); 
     } 

     public static void StartCache() 
     { 
      string lcUrl = "http://localhost/ratingspage/"; 
      // *** Establish the request 

      try 
      { 

       WebClient client = new WebClient(); 
       client.Credentials = new NetworkCredential("xxx", "xxx", 
        "xxx"); 
       byte[] myDataBuffer = client.DownloadData(lcUrl); 


      } 
      catch (Exception ex) 
      { 
       ErrHandler.WriteError(ex.Message + "\n" + 
        ex.StackTrace.ToString()); 
       LogUtil.LogDebugMessages(ex.Message + ":" + 
        ex.StackTrace.ToString()); 
      } 

     } 

     public static void RefreshCache(string key) 
     { 
      string controlname = ""; 
      if (key.ToLower().StartsWith("control:")) 
      { 
       string[] tmp = key.Split(':'); 
       if (tmp.Length > 1) 
        controlname = tmp[1]; 
       else 
        return; 
      } 
      else 
       return; 

      string lcUrl = "http://localhost/ratingspage/Admin/" + " 
       "LoadControl.aspx?CachingSpider=true&Control=" + controlname; 
      string lcHtml = isRefreshingCache.ToString(); 
      // *** Establish the request 

      if (!isRefreshingCache) 
      { 

       isRefreshingCache = true; 
       lcHtml = isRefreshingCache.ToString(); 
       try 
       { 

        WebClient client = new WebClient(); 
        client.Credentials = new NetworkCredential("xxx", 
         "xxx", "xxx"); 
        byte[] myDataBuffer = client.DownloadData(lcUrl); 
        lcHtml = Encoding.ASCII.GetString(myDataBuffer); 

       } 
       catch (Exception ex) 
       { 
        lcHtml = ex.Message; 
        isRefreshingCache = false; 
        ErrHandler.WriteError(ex.Message + "\n" + 
         ex.StackTrace.ToString()); 
        LogUtil.LogDebugMessages(ex.Message + ":" + 
         ex.StackTrace.ToString()); 
       } 
       isRefreshingCache = false; 
      } 



      MailMessage mail = new MailMessage(
       new MailAddress("[email protected]"), 
       new MailAddress("[email protected]")); 
      mail.Subject = "Cache Expire: " + key; 
      mail.Body = string.Format("The Key {0} has expired at {1}", 
       key, DateTime.Now.ToShortDateString() + " " + 
       DateTime.Now.ToShortTimeString()) + "\nRefreshing Cache: " + 
       lcHtml; 
      SmtpClient smtp = new SmtpClient("mercury.utg.uvn.net"); 
      mail.IsBodyHtml = false; 
      try 
      { 

       smtp.Send(mail); 

      } 
      catch (Exception ex) 
      { 
       ErrHandler.WriteError(ex.Message + "\n" + 
        ex.StackTrace.ToString()); 
       LogUtil.LogDebugMessages(ex.Message + ":" + 
        ex.StackTrace.ToString()); 
      } 

     } 
    } 

pour une raison quelconque, quand je vais à la page. Quelque fois les données sont mises en cache et parfois non. Y at-il quelque chose qui cloche

J'ai essayé tissu application, mais puisque le serveur n'a pas 7 iis Je ne suis pas en mesure d'utiliser cette

+0

Etes-vous sûr que vous ne redémarrez pas l'appdomain entre les visites (en appuyant sur F5 pour déboguer vider votre cache). – Paddy

+0

Juste un conseil, je pense que vous pourriez améliorer ceci en n'interlantant pas votre code d'application avec le gestionnaire de cache. Le CacheManager devrait simplement obtenir/définir des clés/valeurs dans n'importe quel système de cache sous-jacent que vous utilisez (redis, other). Dans votre logique métier existante où vous récupéreriez par exemple un utilisateur, vous vérifiez le cache, si c'est nul, vous récupérez de la base de données, mettez dans le cache, puis renvoyez l'élément. Si le cache contenait l'utilisateur, il vous suffit de renvoyer l'utilisateur du cache et d'ignorer la requête de la base de données. –

Répondre

0

La quantité de données que vous pouvez obtenir dans le cache peut être la question.

Si le cache est plein, les données ne seront évidemment pas mises en cache.

Vous pouvez vérifier votre allocation de mémoire en utilisant le process monitor, jetez un oeil dans "Cache Total Entries".

+0

comment puis-je vérifier cela. Je ne pouvais rien trouver – H20rider

+0

Vérifiez cela - http://msdn.microsoft.com/en-us/library/ms972959.aspx#monitor_perf_topic9 Il devrait aider –

+0

merci. Je pense avoir une idée de pourquoi je perds mon cache. J'ai regardé dans la visionneuse d'événement et j'ai vu que j'avais un débordement .net 4 Stack. J'essaie toujours de comprendre ce problème. – H20rider

0

Il me semble que vous pouvez avoir une condition de concurrence dans votre appel RefreshCache. Découvrez cette grande réponse pour des suggestions sur la façon de gérer la synchronisation: Si je vous avais

C# version of java's synchronized keyword?

, je simplifie mon code. Vous ne avez vraiment besoin:

  1. lorsque l'application démarre, charger le cache
  2. lorsque le cache expire, recharger
  3. si un utilisateur tente d'accéder à l'objet mis en cache et misses, le sommeil leur fil pour une deuxième et vérifiez à nouveau
+0

Je ne pense pas que ce soit un problème de synchronisation.Les éléments sont initialement mis en cache mais le problème est qu'il ne reste pas longtemps dans le cache. Je définis le délai d'attente à 24 heures et expire toujours dans une heure. J'ai aussi essayé d'utiliser le H20rider