Этого можно достичь, унаследовав 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);
}