ASP.NET predpomnjenje izhodov (tj. statični HTML) je temeljilo na pomnilniku do .NET 4.0. To pomeni, da če naša stran vsebuje veliko predpomnilnika, je enostavno porabiti lokalni pomnilnik. Zdaj, s pomočjo . OutputCacheProvider v .NET 4.0 imamo več možnosti za ustvarjanje lastnega predpomnilnika. Na primer, HTML izhodni predpomnilnik lahko shranimo v memcached distributed cluster server ali MongoDB (pogosto uporabljena dokumentno usmerjena podatkovna baza, beri ta http://msdn.microsoft.com/zh-cn/magazine/gg650661.aspx). Seveda lahko predpomnilnik shranimo tudi kot datoteko na trdi disk, kar je najcenejši način glede na razširljivost, ta članek pa govori o tem, kako zgraditi prilagojen predpomnilnik datotek.
1:OutputCacheProvider OutputCacheProvider je abstraktni osnovni razred, za katerega moramo preglasiti štiri njegove metode, in sicer: Dodajte metodo za vstavljanje določenega elementa v izhodni predpomnilnik. Get method, ki vrne referenco na določen element v izhodnem predpomnilniku. Odstrani metodo za odstranitev določenega elementa iz izhodnega predpomnilnika. Metoda nastavitve, vstavlja določen element v izhodni predpomnilnik in ga prepiše, če je predpomnjen.
2: Ustvarite svoj razred za upravljanje predpomnjenja datotek Tip je FileCacheProvider, koda pa je naslednja:
- 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;
- }
- }
Kopiraj kodo Obstajata dve mesti, ki potrebujeta posebno pozornost: Pri metodi Add je treba na ta način obdelovati pogojno presojo, sicer bo mehanizem predpomnilnika shranil prvi rezultat, predpomnilnik pa bo potekel po datumu poteka in ga ni mogoče ponovno sestaviti. V primeru programa preprosto postavimo predpomnilnik v mapo predpomnilnika, in v dejanski praksi projekta, glede na to, da bo predpomnjenih strani na tisoče, moramo izvesti klasifikacijo imenikov, sicer bo iskanje in branje datotek predpomnilnika postalo ozko grlo za učinkovitost, kar bo izčrpalo procesor.
3: Konfiguracijska datoteka
V Web.config moramo konfigurirati, da je upravljalnik predpomnilnika prilagojen FileCacheProvider, torej dodati vozlišče pod FileCacheProvider:- <caching>
- <outputCache defaultProvider="FileCache">
- <providers>
- <add name="FileCache" type="MvcApplication2.Common.FileCacheProvider" cachePath="~/Cache" />
- </providers>
- </outputCache>
- </caching>
Kopiraj kodo
4: Uporaba predpomnilnika
Predvidevamo, da če ga uporabljate v nadzoru MVC (če ga želite uporabiti na ASP.NET strani, vključite < % v page@OutputCache VaryByParam = "none" Trajanje="10" %>), in lahko vidite, da Index ni predpomnjen, medtem ko je Index2 predpomnjen 10 sekund.
- 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();
- }
- }
Kopiraj kodo 5: Preverite učinek Zgornja koda, po dostopu do Index2, bo ustvarila datoteko predpomnilnika v mapi Predpomnilnik, kot sledi:
Zdaj ocenimo primerjavo zmogljivosti med izhodnim in izhodnim predpomnilnikom, pri čemer simuliramo 100 sočasnih zahtevkov od 100 uporabnikov na naslednji način:
|