Можно ли перебрать все ключи OutputCache? - PullRequest
4 голосов
/ 14 июня 2010

Можно ли перебрать ключи OutputCache?Я знаю, что вы можете удалить их по отдельности с помощью HttpResponse.RemoveOutputCacheItem (), но есть ли способ, которым я могу перебрать все ключи, чтобы увидеть, что находится в коллекции?

Я искал через Просмотрщик объектов, но ничего не увидел.

В худшем случае я могу вести свой собственный индекс.Так как я делаю все с помощью VaryByCustom, они получают "корм" через метод в global.asax.Меня просто поражает, что должен быть более элегантный способ сделать это.

Ответы [ 4 ]

3 голосов
/ 15 июня 2010

Если вы используете 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;
        }

        ...

    }
}

После этого вы сможете читать ключи, где бы вы их ни хранили.

0 голосов
/ 25 апреля 2013

Этого можно достичь, унаследовав 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);
}
0 голосов
/ 30 декабря 2010

Это делает.

foreach (DictionaryEntry cachedItem in HttpContext.Current.Cache)
{
    Response.Write(String.Format("<b>{0}:</b> {1}<br/>", cachedItem.Key.ToString(), cachedItem.Value.ToString()));
}
0 голосов
/ 14 июня 2010

Я использую это

http://www.codeproject.com/KB/session/exploresessionandcache.aspx

для просмотра кэша и данных сеанса.Скажу только, что показывают только один пул данных.Если у вас больше пулов, вы просто видите тот, на котором находитесь.

...