Denna artikel är en spegelartikel om maskinöversättning, klicka här för att hoppa till originalartikeln.

Utsikt: 16824|Svar: 0

[ASP.NET] Bygg en anpassad filcache ASP.NET prestandaoptimering

[Kopiera länk]
Publicerad på 2015-04-19 22:06:12 | | | |
ASP.NET utdatacaching (dvs. statisk HTML) var minnesbaserad fram till .NET 4.0. Det betyder att om vår plats innehåller mycket cache är det lätt att använda lokalt minne. Nu, med hjälp av . OutputCacheProvider i .NET 4.0, vi har flera alternativ för att skapa vår egen cache. Till exempel kan vi lagra HTML-utdatacachen i en memcached distribuerad klusterserver eller MongoDB (en vanligt använd dokumentorienterad databas, läs detta http://msdn.microsoft.com/zh-cn/magazine/gg650661.aspx). Självklart kan vi också lagra cachen som en fil på hårddisken, vilket är det billigaste sättet att göra det med tanke på skalbarhet, och den här artikeln handlar om hur man bygger en egen filcache.
1:OutputCacheProvider
OutputCacheProvider är en abstrakt basklass som vi behöver åsidosätta fyra av dess metoder, vilka är:
Lägg till metod för att infoga det specificerade objektet i utdatacachen.
get-metoden, som returnerar en referens till det angivna objektet i utdatacachen.
Ta bort metoden för att ta bort det specificerade objektet från utdatacachen.
Set-metoden, infogar det specificerade objektet i utdatacachen och skriver över objektet om det är cachalt.
2: Skapa din egen filcachningshanteringsklass
Typen är FileCacheProvider, och koden är följande:

  1. public class FileCacheProvider : OutputCacheProvider
  2. {
  3.     private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

  4.     public override void Initialize(string name, NameValueCollection attributes)
  5.     {
  6.         base.Initialize(name, attributes);
  7.         CachePath = HttpContext.Current.Server.MapPath(attributes["cachePath"]);
  8.     }

  9.     public override object Add(string key, object entry, DateTime utcExpiry)
  10.     {
  11.         Object obj = Get(key);
  12.         if (obj != null)    //这一步很重要
  13.         {
  14.             return obj;
  15.         }
  16.         Set(key,entry,utcExpiry);
  17.         return entry;
  18.     }

  19.     public override object Get(string key)
  20.     {
  21.         string path = ConvertKeyToPath(key);
  22.         if (!File.Exists(path))
  23.         {
  24.             return null;
  25.         }
  26.         CacheItem item = null;
  27.         using (FileStream file = File.OpenRead(path))
  28.         {
  29.             var formatter = new BinaryFormatter();
  30.             item = (CacheItem)formatter.Deserialize(file);
  31.         }

  32.         if (item.ExpiryDate <= DateTime.Now.ToUniversalTime())
  33.         {
  34.             log.Info(item.ExpiryDate + "*" + key);
  35.             Remove(key);
  36.             return null;
  37.         }
  38.         return item.Item;
  39.     }


  40.     public override void Set(string key, object entry, DateTime utcExpiry)
  41.     {
  42.         CacheItem item = new CacheItem(entry, utcExpiry);
  43.         string path = ConvertKeyToPath(key);
  44.         using (FileStream file = File.OpenWrite(path))
  45.         {
  46.             BinaryFormatter formatter = new BinaryFormatter();
  47.             formatter.Serialize(file, item);
  48.         }
  49.     }
  50.       
  51.     public override void Remove(string key)
  52.     {
  53.         string path = ConvertKeyToPath(key);
  54.         if (File.Exists(path))
  55.             File.Delete(path);
  56.     }

  57.     public string CachePath
  58.     {
  59.         get;
  60.         set;
  61.     }

  62.     private string ConvertKeyToPath(string key)
  63.     {
  64.         string file = key.Replace('/', '-');
  65.         file += ".txt";
  66.         return Path.Combine(CachePath, file);
  67.     }
  68. }

  69. [Serializable]
  70. public class CacheItem
  71. {
  72.     public DateTime ExpiryDate;
  73.     public object Item;

  74.     public CacheItem(object entry, DateTime utcExpiry)
  75.     {
  76.         Item = entry;
  77.         ExpiryDate = utcExpiry;
  78.     }
  79. }
Kopiera koden
Det finns två platser som behöver särskild uppmärksamhet:
I Add-metoden finns det en villkorlig bedömning som måste hanteras på detta sätt, annars kommer cachemekanismen att cachelagra det första resultatet, och cachen upphör efter utgångsdatumet och kommer inte att byggas upp igen.
I exempelprogrammet lägger vi helt enkelt cachen i cachekatalogen, och i verklig projektpraktik, med tanke på att de cachade sidorna kommer att vara tusentals, måste vi göra katalogklassificering, annars blir det en effektivitetsflaskhals att hitta och läsa cachefiler, vilket tömmer CPU:n.
3: Konfigurationsfil

Vi behöver konfigurera i Web.config att cachehanteraren är en anpassad FileCacheProvider, dvs. lägga till en nod under FileCacheProvider:
  1. <caching>
  2.   <outputCache defaultProvider="FileCache">
  3.     <providers>
  4.       <add name="FileCache" type="MvcApplication2.Common.FileCacheProvider" cachePath="~/Cache" />
  5.     </providers>
  6.   </outputCache>
  7. </caching>
Kopiera koden

4: Användning av cache

Vi antar att använda den i MVC:s kontroll (om du vill använda den på en ASP.NET sida, inkludera <% i page@OutputCache VaryByParam="ingen" Duration="10" %>), och du kan se att Index inte matas ut cachad, medan Index2 matas ut cachad i 10 sekunder.
  1. public class HomeController : Controller
  2. {
  3.     private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
  4.     static string s_conn = "Data Source=192.168.0.77;Initial Catalog=luminjidb;User Id=sa;Password=sa;";
  5.     public ActionResult Index()
  6.     {
  7.         using (DataSet ds = Common.SqlHelper.ExecuteDataset(s_conn, CommandType.Text, "select top 1* from NameTb a, DepTb b where a.DepID = b.ID ORDER BY NEWID()"))
  8.         {
  9.             ViewBag.Message = ds.Tables[0].Rows[0]["name"].ToString();
  10.         }
  11.         return View();
  12.     }

  13.     [OutputCache(Duration = 10, VaryByParam = "none")]
  14.     public ActionResult Index2()
  15.     {
  16.         using (DataSet ds = Common.SqlHelper.ExecuteDataset(s_conn, CommandType.Text, "select top 1* from NameTb a, DepTb b where a.DepID = b.ID ORDER BY NEWID()"))
  17.         {
  18.             ViewBag.Message = ds.Tables[0].Rows[0]["name"].ToString();
  19.         }
  20.         return View();
  21.     }
  22. }
Kopiera koden
5: Kontrollera effekten
Koden ovan, efter åtkomst till Index2, kommer att generera en cachefil i cache-mappen enligt följande:

Nu ska vi utvärdera prestandajämförelsen mellan utdatacachen och utgångscachen, och simulera 100 samtidiga förfrågningar från 100 användare enligt följande:








Föregående:Sessionens livscykel
Nästa:C#. .NET för att förhindra SQL-injektionsattacker
Friskrivning:
All programvara, programmeringsmaterial eller artiklar som publiceras av Code Farmer Network är endast för lärande- och forskningsändamål; Ovanstående innehåll får inte användas för kommersiella eller olagliga ändamål, annars kommer användarna att bära alla konsekvenser. Informationen på denna sida kommer från internet, och upphovsrättstvister har inget med denna sida att göra. Du måste helt radera ovanstående innehåll från din dator inom 24 timmar efter nedladdning. Om du gillar programmet, vänligen stöd äkta programvara, köp registrering och få bättre äkta tjänster. Om det finns något intrång, vänligen kontakta oss via e-post.

Mail To:help@itsvse.com