C# 如何获取HttpRuntime.Cache对象的过期日期时间?

C# 如何获取HttpRuntime.Cache对象的过期日期时间?,c#,asp.net,caching,C#,Asp.net,Caching,是否可以获取HttpRuntime.Cache对象的过期日期DateTime 如果是这样,最好的方法是什么?缓存本身不会过期。它可以有项目(过期),也可以没有任何项目。我刚刚浏览了reflector中的System.Web.Caching.Cache。似乎所有涉及到期日的内容都标记为内部。我唯一能找到对它的公共访问的地方是通过Cache.Add和Cache.Insert方法 看来你运气不好,除非你想进行反思,我不建议你这样做,除非你真的需要那个约会 但是,如果您仍然希望这样做,那么下面是一些代码

是否可以获取
HttpRuntime.Cache
对象的过期日期
DateTime


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

缓存本身不会过期。它可以有项目(过期),也可以没有任何项目。

我刚刚浏览了reflector中的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;
}
HttpRuntime.Cache的内部公共getter已替换为静态变量,因此您需要调用/获取静态变量:

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

正如有人在评论中所说,接受的答案在.NET4.7中不起作用

我在试图弄清楚需要做哪些更改才能使它在.NET4.7中工作时遇到了很多麻烦

这是我为使用.NET4.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;
}

你救了我的命!这段代码是什么意思!我永远不会想到这一点,因为我不熟悉系统反射!为什么不建议使用此方法?它是否在查看时加载整个缓存对象?如果您提供如何使用Reflector的步骤,这将对我非常有帮助。。我无法使用此函数,因为它会出现一些错误。这在.NET4.7中不起作用。内部Get方法已被删除。这似乎不再有效,至少在.net 4.5.2中是这样。现在有了一个public Get方法,但它只返回缓存的值。您显然还没有理解这个问题。@Softlion:如果您有问题,为什么不回答这个问题?@Softlion:您愿意解释一下我的回答中的错误吗?我不介意删除答案。问题是关于获取缓存中项目的过期日期。这个答案并没有解决这个问题。一个令人讨厌的方法是在另一个缓存对象中添加此对象的datetime,然后用Date.Now()减去该生存期。您能分享一下吗,如何获取CacheItemPriority?,与过期日期相同。