Как я могу получить дату истечения срока действия объекта HttpRuntime.Cache? - PullRequest
13 голосов
/ 05 декабря 2008

Возможно ли получить срок действия DateTime объекта HttpRuntime.Cache?

Если это так, какой подход лучше всего подходит?

Ответы [ 3 ]

25 голосов
/ 08 декабря 2008

Я только что прошел 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;
}

Начиная с .NET 4.5 внутренний открытый метод получения HttpRuntime.Cache был заменен статическим вариантом, и, таким образом, вам потребуется вызвать / получить статический вариант:

object cacheEntry = Cache.GetType().GetMethod("Get").Invoke(null, new object[] { cacheKey, 1 });
0 голосов
/ 22 октября 2018

Как предположил кто-то в комментариях, принятый ответ не работает в .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;
}
0 голосов
/ 08 декабря 2008

Кеш сам по себе не истекает. Либо он может иметь предметы (срок действия которых истекает), либо вообще не иметь предметов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...