如何获取HttpRuntime.Cache对象的到期日期时间?

时间:2008-12-05 16:53:17

标签: c# asp.net caching

是否可以获得DateTime对象的到期HttpRuntime.Cache

如果是这样,最好的方法是什么?

3 个答案:

答案 0 :(得分:25)

我刚刚浏览了反射器中的System.Web.Caching.Cache。似乎涉及到期日的所有内容都标记为内部。我发现公共访问它的唯一地方是通过Cache.Add和Cache.Insert方法。

所以看起来你运气不好,除非你想通过反思,除非你真的需要那个约会,否则我不建议。

但是如果你想要这样做,那么这里有一些代码可以解决这个问题:

private DateTime GetCacheUtcExpiryDateTime(string cacheKey)
{
    object cacheEntry = Cache.GetType().GetMethod("Get", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(Cache, new object[] { cacheKey, 1 });
    PropertyInfo utcExpiresProperty = cacheEntry.GetType().GetProperty("UtcExpires", BindingFlags.NonPublic | BindingFlags.Instance);
    DateTime utcExpiresValue = (DateTime)utcExpiresProperty.GetValue(cacheEntry, null);

    return utcExpiresValue;
}

Since .NET 4.5 HttpRuntime.Cache的内部公共getter被替换为静态变体,因此您需要调用/获取静态变体:

object cacheEntry = Cache.GetType().GetMethod("Get").Invoke(null, new object[] { cacheKey, 1 });

答案 1 :(得分:0)

正如某人在评论中所建议的那样,接受的答案在.NET 4.7中不起作用

我很难弄清楚要使其在.NET 4.7中工作需要进行哪些更改

这是我的使用.NET 4.7的人的代码

private DateTime GetCacheUtcExpiryDateTime(string cacheKey)
{
    var aspnetcachestoreprovider = System.Web.HttpRuntime.Cache.GetType().GetProperty("InternalCache", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(System.Web.HttpRuntime.Cache, null);
    var intenralcachestore = aspnetcachestoreprovider.GetType().GetField("_cacheInternal", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(aspnetcachestoreprovider);
    Type TEnumCacheGetOptions = System.Web.HttpRuntime.Cache.GetType().Assembly.GetTypes().Where(d => d.Name == "CacheGetOptions").FirstOrDefault();
    object cacheEntry = intenralcachestore.GetType().GetMethod("DoGet", BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Any, new[] { typeof(bool), typeof(string), TEnumCacheGetOptions }, null).Invoke(intenralcachestore, new Object[] { true, cacheKey, 1 }); ;
    PropertyInfo utcExpiresProperty = cacheEntry.GetType().GetProperty("UtcExpires", BindingFlags.NonPublic | BindingFlags.Instance);
    DateTime utcExpiresValue = (DateTime)utcExpiresProperty.GetValue(cacheEntry, null);

    return utcExpiresValue;
}

对于那些希望代码在多种不同环境中运行(使用.NET 4.5的沙盒和使用.NET 4.7的产品)的人,这里有一些补丁工作:

private DateTime GetCacheUtcExpiryDateTime(string cacheKey)
{
    MethodInfo GetCacheEntryMethod = null;
    Object CacheStore = null;
    bool GetterFound = true;

    GetCacheEntryMethod = System.Web.HttpRuntime.Cache.GetType().GetMethod("Get", BindingFlags.Instance | BindingFlags.NonPublic);
    if (GetCacheEntryMethod != null)
    {
        GetterFound = true;
        CacheStore = System.Web.HttpRuntime.Cache;
    }
    else
    {
        var aspnetcachestoreprovider = System.Web.HttpRuntime.Cache.GetType().GetProperty("InternalCache", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(System.Web.HttpRuntime.Cache, null);
        var intenralcachestore = aspnetcachestoreprovider.GetType().GetField("_cacheInternal", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(aspnetcachestoreprovider);
        Type TEnumCacheGetOptions = System.Web.HttpRuntime.Cache.GetType().Assembly.GetTypes().Where(d => d.Name == "CacheGetOptions").FirstOrDefault();
        GetCacheEntryMethod = intenralcachestore.GetType().GetMethod("DoGet", BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Any, new[] { typeof(bool), typeof(string), TEnumCacheGetOptions }, null);
        GetterFound = false;
        CacheStore = intenralcachestore;
    }

    dynamic cacheEntry;
    if (GetterFound)
        cacheEntry = GetCacheEntryMethod.Invoke(CacheStore, new Object[] { cacheKey, 1 });
    else
        cacheEntry = GetCacheEntryMethod.Invoke(CacheStore, new Object[] { true, cacheKey, 1 });

    PropertyInfo utcExpiresProperty = cacheEntry.GetType().GetProperty("UtcExpires", BindingFlags.NonPublic | BindingFlags.Instance);
    DateTime utcExpiresValue = (DateTime)utcExpiresProperty.GetValue(cacheEntry, null);

    return utcExpiresValue;
}

答案 2 :(得分:-5)

缓存本身不会过期。它可以有物品(过期)或者根本没有任何物品。