ASP.NET изходното кеширане (т.е. статичен HTML) беше базирано на памет до .NET 4.0. Това означава, че ако нашият сайт съдържа много кеш, лесно се консумира локална памет. Сега, с помощта на . OutputCacheProvider в .NET 4.0 имаме няколко опции за създаване на собствен кеш. Например, можем да съхраняваме HTML изходния кеш в memcached разпределен клъстер сървър или MongoDB (често използвана документно-ориентирана база данни, прочетете тази http://msdn.microsoft.com/zh-cn/magazine/gg650661.aspx). Разбира се, можем също да съхраняваме кеша като файл на твърдия диск, което е най-евтиният начин да го направим, като се има предвид мащабируемостта, а тази статия е за това как да се създаде персонализиран файлов кеш.
1:OutputCacheProvider OutputCacheProvider е абстрактен базов клас, който трябва да презапише четири от неговите методи, а именно: Добавете метод за вмъкване на зададен елемент в изходния кеш. Get метод, който връща препратка към посочения елемент в изходния кеш. Метод за премахване на зададен елемент от изходния кеш. Задайте метода, вмъквате зададения елемент в изходния кеш и презаписвате елемента, ако е кеширан.
2: Създайте свой собствен клас за обработка на кеширане на файлове Типът е FileCacheProvider, а кодът е следният:
- 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;
- }
- }
Копирай код Има две места, които заслужават специално внимание: В метода Add има условна преценка, която трябва да се обработи по този начин, в противен случай механизмът за кеширане ще кешира първия резултат, а кешът ще изтече след изтичащата дата и няма да бъде възстановен. В примерната програма просто поставяме кеша в кеш директорията, и в реалната проектна практика, като се има предвид, че кешираните страници ще са хиляди, трябва да се извършва класификация на директории, иначе намирането и четенето на кеш файлове ще се превърне в тесно място за ефективността, което ще изтощи процесора.
3: Конфигурационен файл
Трябва да конфигурираме в Web.config така, че обработващият кеш да е персонализиран FileCacheProvider, т.е. да добавим възел под FileCacheProvider:- <caching>
- <outputCache defaultProvider="FileCache">
- <providers>
- <add name="FileCache" type="MvcApplication2.Common.FileCacheProvider" cachePath="~/Cache" />
- </providers>
- </outputCache>
- </caching>
Копирай код
4: Използване на кеш
Приемаме, че при използване на MVC контрол (ако искате да го използвате в ASP.NET страница, включете <% в page@OutputCache VaryByParam="none" Duration="10" %>), и ще видите, че Index не е изходно кеширан, докато Index2 е изходен кеширан за 10 секунди.
- 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();
- }
- }
Копирай код 5: Проверете ефекта Горният код, след достъп до Index2, ще генерира кеш файл в папката Cache, както следва:
Сега нека оценим сравнението на производителността между изходния кеш и изходния кеш, като симулираме 100 едновременни заявки от 100 потребители, както следва:
|