ASP.NET utdatacaching (dvs. statisk HTML) var minnebasert frem til .NET 4.0. Dette betyr at hvis nettstedet vårt inneholder mye cache, er det lett å bruke lokalt minne. Nå, med hjelp av . OutputCacheProvider i .NET 4.0, vi har flere alternativer for å lage vår egen cache. For eksempel kan vi lagre HTML-utdatacachen i en memcached distribuert klyngeserver eller MongoDB (en ofte brukt dokumentorientert database, les dette http://msdn.microsoft.com/zh-cn/magazine/gg650661.aspx). Selvfølgelig kan vi også lagre cachen som en fil på harddisken, noe som er den billigste måten å gjøre det på med tanke på skalerbarhet, og denne artikkelen handler om hvordan man bygger en egendefinert filcache.
1:OutputCacheProvider OutputCacheProvider er en abstrakt baseklasse hvor vi må overstyre fire av metodene, som er: Legg til metode for å sette inn det spesifiserte elementet i utdatacachen. Get-metoden, som returnerer en referanse til det spesifiserte elementet i utdatacachen. Fjern metode for å fjerne det spesifiserte elementet fra utdatacachen. Sett-metoden, setter inn det spesifiserte elementet i utdatacachen, og overskriver elementet hvis det er cachet.
2: Lag din egen fil-cache-håndteringsklasse Typen er FileCacheProvider, og koden er som følger:
- public class FileCacheProvider : OutputCacheProvider
- {
- private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-
- public override void Initialize(string name, NameValueCollection attributes)
- {
- base.Initialize(name, attributes);
- CachePath = HttpContext.Current.Server.MapPath(attributes["cachePath"]);
- }
-
- public override object Add(string key, object entry, DateTime utcExpiry)
- {
- Object obj = Get(key);
- if (obj != null) //这一步很重要
- {
- return obj;
- }
- Set(key,entry,utcExpiry);
- return entry;
- }
-
- public override object Get(string key)
- {
- string path = ConvertKeyToPath(key);
- if (!File.Exists(path))
- {
- return null;
- }
- CacheItem item = null;
- using (FileStream file = File.OpenRead(path))
- {
- var formatter = new BinaryFormatter();
- item = (CacheItem)formatter.Deserialize(file);
- }
-
- if (item.ExpiryDate <= DateTime.Now.ToUniversalTime())
- {
- log.Info(item.ExpiryDate + "*" + key);
- Remove(key);
- return null;
- }
- return item.Item;
- }
-
-
- public override void Set(string key, object entry, DateTime utcExpiry)
- {
- CacheItem item = new CacheItem(entry, utcExpiry);
- string path = ConvertKeyToPath(key);
- using (FileStream file = File.OpenWrite(path))
- {
- BinaryFormatter formatter = new BinaryFormatter();
- formatter.Serialize(file, item);
- }
- }
-
- public override void Remove(string key)
- {
- string path = ConvertKeyToPath(key);
- if (File.Exists(path))
- File.Delete(path);
- }
-
- public string CachePath
- {
- get;
- set;
- }
-
- private string ConvertKeyToPath(string key)
- {
- string file = key.Replace('/', '-');
- file += ".txt";
- return Path.Combine(CachePath, file);
- }
- }
-
- [Serializable]
- public class CacheItem
- {
- public DateTime ExpiryDate;
- public object Item;
-
- public CacheItem(object entry, DateTime utcExpiry)
- {
- Item = entry;
- ExpiryDate = utcExpiry;
- }
- }
Kopier koden Det er to steder som trenger spesiell oppmerksomhet: I Add-metoden må det håndteres en betinget vurdering på denne måten, ellers vil caching-mekanismen cache det første resultatet, og cachen vil utløpe etter utløpsdatoen og vil ikke bli bygget opp på nytt. I eksempelprogrammet legger vi ganske enkelt cachen i cache-katalogen, og i faktisk prosjektpraksis, med tanke på at de bufrede sidene vil være tusenvis, må vi gjøre katalogklassifisering, ellers vil det å finne og lese cache-filer bli en effektivitetsflaskehals som tapper CPU-en.
3: Konfigurasjonsfil
Vi må konfigurere i Web.config at cache-håndtereren er en egendefinert FileCacheProvider, altså legge til en node under FileCacheProvider:- <caching>
- <outputCache defaultProvider="FileCache">
- <providers>
- <add name="FileCache" type="MvcApplication2.Common.FileCacheProvider" cachePath="~/Cache" />
- </providers>
- </outputCache>
- </caching>
Kopier koden
4: Bruk av cache
Vi antar at bruk av det i MVCs kontroll (hvis du vil bruke det på en ASP.NET side, inkluder < % i page@OutputCache VaryByParam="none" Varighet="10" %>), og du kan se at Index ikke blir skrevet ut i cache, mens Index2 er cachet i 10 sekunder.
- public class HomeController : Controller
- {
- private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
- static string s_conn = "Data Source=192.168.0.77;Initial Catalog=luminjidb;User Id=sa;Password=sa;";
- public ActionResult Index()
- {
- 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()"))
- {
- ViewBag.Message = ds.Tables[0].Rows[0]["name"].ToString();
- }
- return View();
- }
-
- [OutputCache(Duration = 10, VaryByParam = "none")]
- public ActionResult Index2()
- {
- 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()"))
- {
- ViewBag.Message = ds.Tables[0].Rows[0]["name"].ToString();
- }
- return View();
- }
- }
Kopier koden 5: Sjekk effekten Koden ovenfor, etter tilgang til Index2, vil generere en cache-fil i cache-mappen, som følger:
La oss nå evaluere ytelsessammenligningen mellom output-cachen og output-cachen, og simulere 100 samtidige forespørsler fra 100 brukere som følger:
|