2009-02-19 29 views
27

Tôi đang sử dụng OutputCache về kiểm soát webuser tôi (ascx)Bất kỳ cách nào để xóa/xóa/loại bỏ OutputCache?

<%@ OutputCache Duration="1000" VaryByParam="none" %> 

Tôi muốn giữ lại bộ nhớ cache cho 1000 giây tiếp theo, nhưng khi một trang cụ thể trên trang web của tôi được nạp, tôi muốn xóa/xóa/làm mới bộ nhớ cache. Giống như, tôi muốn xóa bộ nhớ cache khi MyPage.aspx được tải. Tôi có thể tuôn ra bộ nhớ cache theo chương trình không?

Trang duy nhất của nó là bộ nhớ cache, do đó không có phiên bản nào đủ điều kiện để xóa bộ nhớ cache.

Cảm ơn sự giúp đỡ của bạn trước.

Trả lời

3

Chỉnh sửa: Nếu bạn đã bật bộ đệm hạt nhân trên II6 +, bạn sẽ cần phải đi theo lời khuyên của Luke và sử dụng tiêu đề VaryByCustom, vì bộ nhớ cache ASP.NET sẽ không ảnh hưởng đến bộ nhớ cache của hạt nhân.

OutputCache được lưu trữ trong ASP.NET Cache, vì vậy bạn chỉ có thể gọi Cache.Remove:

List<string> keys = new List<string>(); 

foreach(string key in HttpRuntime.Cache) 
{ 
    keys.Add(key); 
} 

foreach(string key in keys) 
{ 
    Cache.Remove(key); 
} 

di chúc này, tuy nhiên, loại bỏ tất cả các mục bộ nhớ cache, trong đó có mục tùy chỉnh thêm bằng cách mã của bạn.

+4

Bạn có chắc đây là bộ nhớ cache giống nhau không? Tôi nghĩ rằng OutputCache là một điều IIS. Tôi không nghĩ rằng công trình này. –

+0

Điểm tốt, tôi quên bộ nhớ cache hạt nhân –

+1

Bộ nhớ đệm hạt nhân được bật theo mặc định trong IIS7: http://technet.microsoft.com/en-us/library/cc731903(v=ws.10).aspx Vì vậy, nếu bạn chưa bao giờ cấu hình này, bạn đã kích hoạt nó. –

33

Bạn có thể sử dụng thông số VaryByCustom cho việc này.

Trong điều khiển người dùng của bạn, bạn sẽ có những điều sau đây:

<%@ OutputCache Duration="1000" VaryByParam="None" VaryByCustom="MyKey" %> 

Sau đó, bạn sẽ ghi đè lên các phương pháp GetVaryByCustomString trong Global.asax của bạn như vậy:

public override string GetVaryByCustomString(HttpContext context, string arg) 
{ 
    if (arg == "MyKey") 
    { 
     object o = context.Current.Application["MyGuid"]; 
     if (o == null) 
     { 
      o = Guid.NewGuid(); 
      context.Current.Application["MyGuid"] = o; 
     } 
     return o.ToString(); 
    } 
    return base.GetVaryByCustomString(context, arg); 
} 

Cuối cùng trong MyPage.aspx bạn sẽ làm điều này :

Application["MyGuid"] = Guid.NewGuid(); 

Làm thế nào để nó hoạt động?

Bất cứ khi nào bộ điều khiển của bạn được lưu vào bộ nhớ cache, nó được liên kết với một chuỗi (chuỗi được trả về từ phương pháp GetVaryByCustomString khi khóa của bạn được chuyển vào khóa VaryByCustom).

Bất cứ khi nào điều khiển được sử dụng sau đó, GetVaryByCustomString được gọi lại. Nếu chuỗi được trả về khớp với phiên bản được lưu trong bộ nhớ cache của kiểm soát thì phiên bản được lưu trong bộ nhớ cache sẽ được sử dụng.

Trong trường hợp của chúng tôi, "MyKey" được chuyển vào GetVaryByCustomString và trả về bất kỳ nội dung nào được lưu trữ trong Application["MyGuid"].

Bất cứ khi nào MyPage.aspx được gọi, nó thay đổi Application["MyGuid"] thành giá trị ngẫu nhiên mới.

Khi điều khiển của bạn được sử dụng tiếp theo, phương pháp GetVaryByCustomString sẽ trả về giá trị mới và vì không có phiên bản được lưu trong bộ điều khiển được liên kết với giá trị đó, điều khiển sẽ được tạo lại. (Kiểm soát sau đó sẽ được lưu trữ và liên kết với giá trị mới, để tiếp tục cho đến khi cuộc gọi tiếp theo đến MyPage.aspx v.v.)

Có tổng quan here.

+0

Google có xóa bản sao trước đó hoặc giữ bản sao 2 không? – TheGateKeeper

+1

Điều này không thực sự xóa bất cứ điều gì từ bộ nhớ cache, chỉ cần thêm một khóa duy nhất mới cho sự xuất hiện của một bộ nhớ cache rõ ràng, do đó, có bây giờ sẽ có hai bản sao của dữ liệu được lưu trữ trong bộ nhớ. Nếu bạn đã sử dụng VaryByCustom ở nơi khác trên trang web, bạn có thể sẽ cần phải sửa đổi mã trên để gắn GUID vào các chuỗi VaryByCustom hiện có. –

+0

Phương pháp này hoạt động thành công. Cảm ơn lời khuyên này. Người đàn ông làm việc tốt. –

10

Bạn có thể sử dụng HttpResponse.RemoveOutputCacheItem hoặc HttpResponse.AddCacheItemDependency để làm mất hiệu lực mục nhập bộ nhớ cache đầu ra.

+0

Tôi đã kết thúc việc tương tự: http://stackoverflow.com/questions/11585/clearing-page-cache-in-asp-net/2876701#2876701 – Kevin

+2

Nếu OutputCacheProvider của bạn không phải là mặc định (ví dụ: bạn ' tái sử dụng AppFabric hoặc MemCached) các phương pháp này sẽ không hoạt động. Chỉ cần một người đứng lên cho bất cứ ai xem xét lựa chọn của họ ... Tôi nghĩ rằng câu trả lời VaryByCustom là thích hợp hơn bởi vì nó sẽ làm việc trong cả hai trường hợp. –

+0

Thực sự cả hai đều thích hợp hơn; VaryByCustom cho bạn một số những gì anh ta hỏi, nhưng nếu phiên bản trước của trang thực sự chết mãi mãi, không bao giờ được sử dụng lại, bạn có thể giảm áp lực bộ nhớ cache bằng cách loại bỏ nó một cách rõ ràng với RemoveOutputCacheItem. –

2

bạn có thể thêm HttpResponse.RemoveOutputCacheItem ("/ YourCachePageName.aspx"); dòng mã trong sự kiện tải trang của trang, tải trong đó bạn mong đợi bộ nhớ cache của trang được lưu trong bộ nhớ cache bị tắt.

8

Đó là một chút của một sledgehammer để crack một loại hạt cách tiếp cận nhưng nó là cách đơn giản và hiệu quả nhất để hoàn toàn xóa/tuôn ra bộ nhớ cache của một ứng dụng mà tôi tìm thấy.

Đơn giản chỉ cần gọi:

HttpRuntime.UnloadAppDomain(); 

này có tác động tương tự như tái chế hồ bơi ứng dụng. Không phù hợp trong mọi tình huống nhưng chắc chắn sẽ hoàn thành công việc.

+0

Tôi đồng ý. Sau khi kiệt sức nhiều kỹ thuật khác nhau, đây là kỹ thuật duy nhất đáng tin cậy. –

+0

Đây không phải là phương pháp đáng tin cậy duy nhất để xóa bộ nhớ cache. Điều đó ngụ ý rằng không có cơ chế nào khác hoạt động, được in đậm. Việc tải miền ứng dụng là khá nặng. –

4

Bằng cách cảm hứng về bài đăng khác, đoạn sau loại bỏ thành công tất cả các trang lưu trữ bởi OutputCache trong asp.net bằng cách sử dụng phản ánh:

 public static void ClearOutputCache() 
     { 

      var runtimeType = typeof(HttpRuntime); 

      var ci = runtimeType.GetProperty(
       "CacheInternal", 
       BindingFlags.NonPublic | BindingFlags.Static); 

      var cache = ci.GetValue(ci, new object[0]); 

      var cachesInfo = cache.GetType().GetField(
       "_caches", 
       BindingFlags.NonPublic | BindingFlags.Instance); 
      var cacheEntries = cachesInfo.GetValue(cache); 

      var outputCacheEntries = new List<object>(); 

      foreach (Object singleCache in cacheEntries as Array) 
      { 
       var singleCacheInfo = 
       singleCache.GetType().GetField("_entries", 
        BindingFlags.NonPublic | BindingFlags.Instance); 
       var entries = singleCacheInfo.GetValue(singleCache); 

       foreach (DictionaryEntry cacheEntry in entries as Hashtable) 
       { 
        var cacheEntryInfo = cacheEntry.Value.GetType().GetField("_value", 
         BindingFlags.NonPublic | BindingFlags.Instance); 
        var value = cacheEntryInfo.GetValue(cacheEntry.Value); 
        if (value.GetType().Name == "CachedRawResponse") 
        { 
         var key = (string)cacheEntry.Value.GetType().BaseType.GetField("_key", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(cacheEntry.Value); 
         key = key.Substring(key.IndexOf("/")); 
         outputCacheEntries.Add(key); 
        } 
       } 
      } 
      foreach (string key in outputCacheEntries) 
      { 
       HttpResponse.RemoveOutputCacheItem(key); 
      } 
     } 
+1

Câu trả lời này đã giúp tôi rất nhiều. Có thể lặp qua bộ nhớ đệm và lấy chìa khóa cho tôi thấy chính xác những gì tôi cần. Cảm ơn. –

+1

Tôi đã cố gắng sử dụng mã nhưng tôi gặp lỗi thời gian chạy System.NullReferenceException: var cacheEntries = cachesInfo.GetValue (cache); – Dallas

Các vấn đề liên quan