ASP.NET caching output (yaitu HTML statis) berbasis memori hingga .NET 4.0. Artinya, jika situs kami berisi banyak cache, mudah untuk mengkonsumsi memori lokal. Sekarang, dengan bantuan . OutputCacheProvider di .NET 4.0, kami memiliki beberapa opsi untuk membuat cache kami sendiri. Misalnya, kita dapat menyimpan cache keluaran HTML di server klaster terdistribusi memcached atau MongoDB (database berorientasi dokumen yang umum digunakan, baca http://msdn.microsoft.com/zh-cn/magazine/gg650661.aspx ini). Tentu saja, kita juga dapat menyimpan cache sebagai file di hard drive, yang merupakan cara termurah untuk melakukannya dengan mempertimbangkan skalabilitas, dan artikel ini adalah tentang cara membangun cache file khusus.
1:Penyedia CacheOutput OutputCacheProvider adalah kelas dasar abstrak yang perlu kita ganti empat metodenya, yaitu: Tambahkan metode untuk memasukkan item yang ditentukan ke dalam cache output. Get, yang mengembalikan referensi ke item yang ditentukan dalam cache output. Hapus metode untuk menghapus item yang ditentukan dari cache output. Set, menyisipkan item yang ditentukan ke dalam cache output, dan menimpa item jika di-cache.
2: Buat kelas penanganan cache file Anda sendiri Jenisnya adalah FileCacheProvider, dan kodenya adalah sebagai berikut:
- 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;
- }
- }
Salin kode Ada dua tempat yang membutuhkan perhatian khusus: Dalam metode Add, ada penilaian bersyarat yang harus ditangani dengan cara ini, jika tidak, mekanisme caching akan menyimpan hasil pertama dalam cache, dan cache akan kedaluwarsa setelah tanggal kedaluwarsa dan tidak akan dibangun kembali. Dalam contoh program, kita cukup menempatkan cache di direktori cache, dan dalam praktik proyek aktual, mengingat halaman yang di-cache akan ribuan, kita harus melakukan klasifikasi direktori, jika tidak, menemukan dan membaca file cache akan menjadi kemacetan efisiensi, yang akan menguras CPU.
3: File konfigurasi
Kita perlu mengonfigurasi di Web.config bahwa penangan cache adalah FileCacheProvider khusus, yaitu menambahkan node di bawah FileCacheProvider:- <caching>
- <outputCache defaultProvider="FileCache">
- <providers>
- <add name="FileCache" type="MvcApplication2.Common.FileCacheProvider" cachePath="~/Cache" />
- </providers>
- </outputCache>
- </caching>
Salin kode
4: Penggunaan cache
Kami berasumsi bahwa menggunakannya dalam kontrol MVC (jika Anda ingin menggunakannya di halaman ASP.NET, sertakan <% dalam page@OutputCache VaryByParam="none" Duration="10" %>), dan Anda dapat melihat bahwa Index tidak di-cache output, sedangkan Index2 di-cache selama 10 detik.
- 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();
- }
- }
Salin kode 5: Periksa efeknya Kode di atas, setelah mengakses Index2, akan menghasilkan file cache di folder Cache, sebagai berikut:
Sekarang, mari kita evaluasi perbandingan performa antara cache output dan cache output, mensimulasikan 100 permintaan bersamaan dari 100 pengguna sebagai berikut:
|