2010-06-14 41 views
4

是否可以迭代OutputCache鍵?我知道你可以通過HttpResponse.RemoveOutputCacheItem()單獨刪除它們,但有沒有辦法我可以迭代所有的鍵來查看集合中的內容?是否有可能迭代所有OutputCache鍵?

我通過對象查看器搜索,但沒有看到任何東西。

最壞的情況下,我可以維護我自己的索引。由於我正在通過VaryByCustom完成所有工作,因此他們通過global.asax中的方法進行「餵食」。這讓我覺得必須有更優雅的方式來做到這一點。

回答

2

如果您使用ASP.NET 4.0,您可以通過編寫自己的OutputCacheProvider來完成此操作。這將使你的鑰匙存放在該點,該項目被緩存的能力:

namespace StackOverflowOutputCacheProvider 
{ 
    public class SOOutputCacheProvider: OutputCacheProvider 
    { 
     public override object Add(string key, object entry, DateTime utcExpiry) 
     { 
      // Do something here to store the key 

      // Persist the entry object in a persistence layer somewhere e.g. in-memory cache, database, file system 

      return entry; 
     } 

     ... 

    } 
} 

你會那麼可以從任何地方你已經將它們存儲讀取按鍵失靈。

1

這就行了。

foreach (DictionaryEntry cachedItem in HttpContext.Current.Cache) 
{ 
    Response.Write(String.Format("<b>{0}:</b> {1}<br/>", cachedItem.Key.ToString(), cachedItem.Value.ToString())); 
} 
+1

不,等等,這不是OutputCache,抱歉 - 這是常規緩存。 – Deane 2010-12-30 14:17:18

0

這可以通過繼承MemoryCache並通過自定義OutputCacheProvider實現公開枚舉器來實現。請記住,枚舉器會鎖定緩存。枚舉緩存應該很少執行。

namespace Caching 
{ 
    internal class MemoryCacheInternal : System.Runtime.Caching.MemoryCache 
    { 

    public MemoryCacheInternal(string name, System.Collections.Specialized.NameValueCollection config = null) : base(name, config) 
    { 
    } 

    public System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, object>> Enumerator() 
    { 
     return base.GetEnumerator(); 
    } 

    } 
} 

在緩存OutputCacheProvider

using System.Web.Caching; 
using System.Collections.Generic; 

namespace Caching 
{ 

public class EnumerableMemoryOutputCacheProvider : OutputCacheProvider, IEnumerable<KeyValuePair<string, object>>, IDisposable 
{ 

    private static readonly MemoryCacheInternal _cache = new MemoryCacheInternal("EnumerableMemoryOutputCache"); 

    public override object Add(string key, object entry, System.DateTime utcExpiry) 
    { 
     return _cache.AddOrGetExisting(key, entry, UtcDateTimeOffset(utcExpiry)); 
    } 

    public override object Get(string key) 
    { 
     return _cache.Get(key); 
    } 

    public override void Remove(string key) 
    { 
     _cache.Remove(key); 
    } 

    public override void Set(string key, object entry, System.DateTime utcExpiry) 
    { 
     _cache.Set(key, entry, UtcDateTimeOffset(utcExpiry)); 
    } 

    public IEnumerator<KeyValuePair<string,object>> GetEnumerator() 
    { 
     return _cache.Enumerator(); 
    } 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return _cache.Enumerator(); 
    } 

    private DateTimeOffset UtcDateTimeOffset(System.DateTime utcExpiry) 
    { 
     DateTimeOffset dtOffset = default(DateTimeOffset); 
     if ((utcExpiry.Kind == DateTimeKind.Unspecified)) { 
      dtOffset = DateTime.SpecifyKind(utcExpiry, DateTimeKind.Utc); 
     } else { 
      dtOffset = utcExpiry; 
     } 
     return dtOffset; 
    } 


    #region "IDisposable Support" 
    // To detect redundant calls 
    private bool disposedValue; 

    // IDisposable 
    protected virtual void Dispose(bool disposing) 
    { 
     if (!this.disposedValue) { 
      if (disposing) { 
       _cache.Dispose(); 
      } 
     } 
     this.disposedValue = true; 
    } 

    public void Dispose() 
    { 
     // Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above. 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
    #endregion 


} 
} 

配置自定義實現自定義OutputCacheProvider

<system.web> 
<caching> 
    <outputCache defaultProvider="EnumerableMemoryCache"> 
    <providers> 
     <add name="EnumerableMemoryCache" 
     type="Caching.EnumerableMemoryOutputCacheProvider, MyAssemblyName"/> 
    </providers> 
    </outputCache> 
    <outputCacheSettings> 
    <outputCacheProfiles>  
     <add name="ContentAllParameters" enabled="false" duration="14400" location="Any" varyByParam="*"/> 
    </outputCacheProfiles> 
    </outputCacheSettings> 
</caching> 
</system.web> 

枚舉,在這種情況下,刪除緩存項。

OutputCacheProvider provider = OutputCache.Providers[OutputCache.DefaultProviderName]; 
if (provider == null) return; 
IEnumerable<KeyValuePair<string, object>> keyValuePairs = provider as IEnumerable<KeyValuePair<string, object>>; 
if (keyValuePairs == null) return; 
foreach (var keyValuePair in keyValuePairs) 
{ 
    provider.Remove(keyValuePair.Key); 
} 
相關問題