是否可以提取MemoryCache
对象的内容,包括:
答案 0 :(得分:0)
提取缓存项目键和值很简单,并在Internet上的其他地方介绍。经过一些研究后,似乎有方法为每个项目提取到期时间。我们必须使用Reflection,因为框架不会公开MemoryCache
的内部对象。
我们将首先创建一个类来存储每个缓存项的信息:
public class MemoryCacheItemInfo
{
public string Key { get; private set; }
public object CacheItemValue { get; private set; }
public DateTime Created { get; private set; }
public DateTime LastUpdateUsage { get; private set; }
public DateTime AbsoluteExpiry { get; private set; }
public TimeSpan SlidingExpiry { get; private set; }
public MemoryCacheItemInfo(string key, object cacheItemValue,
DateTime created, DateTime lastUpdateUsage, DateTime absoluteExpiry,
TimeSpan slidingExpiry)
{
this.Key = key;
this.CacheItemValue = cacheItemValue;
this.Created = created;
this.LastUpdateUsage = lastUpdateUsage;
this.AbsoluteExpiry = absoluteExpiry;
this.SlidingExpiry = slidingExpiry;
}
}
现在,我们将使用Reflection访问私有MemoryCache
字段:
public static MemoryCacheItemInfo[] GetCacheItemInfo(this MemoryCache cache)
{
BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
FieldInfo field = typeof (MemoryCache).GetField("_stores", bindFlags);
object[] cacheStores = (object[]) field.GetValue(cache);
List<MemoryCacheItemInfo> info = new List<MemoryCacheItemInfo>();
foreach (object cacheStore in cacheStores)
{
Type cacheStoreType = cacheStore.GetType();
FieldInfo lockField = cacheStoreType.GetField("_entriesLock", bindFlags);
object lockObj = lockField.GetValue(cacheStore);
lock (lockObj)
{
FieldInfo entriesField = cacheStoreType.GetField("_entries", bindFlags);
Hashtable entriesCollection = (Hashtable) entriesField.GetValue(cacheStore);
foreach (DictionaryEntry cacheItemEntry in entriesCollection)
{
Type cacheItemValueType = cacheItemEntry.Value.GetType();
string key = (string) cacheItemEntry.Key.GetType().GetProperty("Key", bindFlags).GetValue(cacheItemEntry.Key);
PropertyInfo value = cacheItemValueType.GetProperty("Value", bindFlags);
PropertyInfo utcCreated = cacheItemValueType.GetProperty("UtcCreated", bindFlags);
PropertyInfo utcLastUpdateUsage = cacheItemValueType.GetProperty("UtcLastUpdateUsage", bindFlags);
PropertyInfo utcAbsoluteExpiry = cacheItemValueType.GetProperty("UtcAbsExp", bindFlags);
PropertyInfo utcSlidingExpiry = cacheItemValueType.GetProperty("SlidingExp", bindFlags);
MemoryCacheItemInfo mcii = new MemoryCacheItemInfo(
key,
value.GetValue(cacheItemEntry.Value),
((DateTime) utcCreated.GetValue(cacheItemEntry.Value)).ToLocalTime(),
((DateTime) utcLastUpdateUsage.GetValue(cacheItemEntry.Value)).ToLocalTime(),
((DateTime) utcAbsoluteExpiry.GetValue(cacheItemEntry.Value)).ToLocalTime(),
((TimeSpan) utcSlidingExpiry.GetValue(cacheItemEntry.Value))
);
info.Add(mcii);
}
}
}
return info.ToArray();
}
此方法效率不高,不建议用于生产环境。
此外,Microsoft未正式支持访问MemoryCache
个私有字段。 MemoryCache
对象的内部结构将来可能会发生变化,这将破坏此代码。