ASP.net Cache Absolute Expiration не работает - PullRequest
15 голосов
/ 05 мая 2011

Я храню одно целочисленное значение в HttpContext.Cache с абсолютным временем истечения 5 минут. Однако после ожидания 6 минут (или дольше) целочисленное значение все еще находится в кэше (то есть оно никогда не удаляется, даже если истек абсолютный срок действия). Вот код, который я использую:

public void UpdateCountFor(string remoteIp)
{
    // only returns true the first time its run
    // after that the value is still in the Cache
    // even after the absolute expiration has passed
    // so after that this keeps returning false
    if (HttpContext.Current.Cache[remoteIp] == null)
    {
        // nothing for this ip in the cache so add the ip as a key with a value of 1
        var expireDate = DateTime.Now.AddMinutes(5);
        // I also tried:
        // var expireDate = DateTime.UtcNow.AddMinutes(5); 
        // and that did not work either.
        HttpContext.Current.Cache.Insert(remoteIp, 1, null, expireDate, Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
    }
    else
    {
        // increment the existing value
        HttpContext.Current.Cache[remoteIp] = ((int)HttpContext.Current.Cache[remoteIp]) + 1;
    }
}

При первом запуске UpdateCountFor ("127.0.0.1") он вставляет 1 в кэш с ключом "127.0.0.1" и истекает через 5 минут, как и ожидалось. Каждый последующий запуск увеличивает значение в кэше. Однако после 10 минут ожидания он продолжает увеличивать значение в кэше. Значение никогда не истекает и никогда не удаляется из кэша. Почему это так?

Насколько я понимаю, абсолютное время истечения означает, что предмет будет удален приблизительно в это время. Я делаю что-то неправильно? Я что-то неправильно понимаю?

Я ожидаю, что значение будет удалено из кэша через 5 минут, однако оно будет оставаться там до тех пор, пока я не перестрою проект.

Это все работает в .NET 4.0 на моем локальном компьютере.

Ответы [ 3 ]

15 голосов
/ 06 мая 2011

Оказывается, эта строка:

HttpContext.Current.Cache[remoteIp] = ((int)HttpContext.Current.Cache[remoteIp]) + 1;

удаляет предыдущее значение и повторно вставляет значение без абсолютного или скользящего времени истечения. Чтобы обойти это, мне нужно было создать вспомогательный класс и использовать его так:

public class IncrementingCacheCounter
{
    public int Count;
    public DateTime ExpireDate;
}

public void UpdateCountFor(string remoteIp)
{
    IncrementingCacheCounter counter = null;
    if (HttpContext.Current.Cache[remoteIp] == null)
    {
        var expireDate = DateTime.Now.AddMinutes(5);
        counter = new IncrementingCacheCounter { Count = 1, ExpireDate = expireDate };
    }
    else
    {
        counter = (IncrementingCacheCounter)HttpContext.Current.Cache[remoteIp];
        counter.Count++;
    }
    HttpContext.Current.Cache.Insert(remoteIp, counter, null, counter.ExpireDate, Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
}

Это позволит обойти проблему и позволить счетчику правильно истечь в абсолютное время, но при этом разрешить его обновление.

4 голосов
/ 05 мая 2011

Попробуйте использовать DateTime.UtcNow, чтобы рассчитать период ожидания вместо datetime.Now. Возможно, вы столкнулись с проблемой, описанной ниже:

absoluteExpiration Тип: System.DateTime время, когда вставленный объект истекает и удаляется из кеша. Во избежание возможно проблемы с местным временем, такие как изменения от стандартного времени до летнего времени время, используйте UtcNow, а не сейчас для значение этого параметра. Если вы используете абсолютное истечение срока Параметр slideExpiration должен быть NoSlidingExpiration.

0 голосов
/ 23 декабря 2014

Есть более простой ответ, чем то, что написал смок.Используя этот пример в качестве отправной точки, обновленный код ниже работает и не требует повторной вставки.Это работает потому, что классы являются ссылочными типами.Таким образом, когда вы обновляете счетчик внутри экземпляра класса, это не заставляет кеш запускать обновление.

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