Срок действия кэша истекает до того, как он должен - PullRequest
4 голосов
/ 24 января 2012

Может кто-нибудь помочь мне здесь? У меня есть следующий код для хранения и восстановления улова, однако он не работает. Срок действия кеша истекает через несколько минут, даже если я установил его на 14 дней в скольжении. Заранее спасибо!

public static List<ReplyDTO> VideoCommentList()
{
     List<ReplyDTO> replyList = new List<ReplyDTO>();
     if (HttpRuntime.Cache["videoComment"] == null)
     {
         HttpRuntime.Cache.Remove("videoComment");
         HttpRuntime.Cache.Insert("videoComment", replyList, null, Cache.NoAbsoluteExpiration, TimeSpan.FromDays(14));
     }
     else
     {
         replyList = (List<ReplyDTO>)HttpRuntime.Cache["videoComment"];
     }

     if (replyList.Count > 8)
     {
         replyList = replyList.OrderByDescending(x => x.DateCreated).Take(8).ToList();
     }
     else
     {
         replyList = replyList.OrderByDescending(x => x.DateCreated).ToList();
     }
     return replyList;
}

public static List<ReplyDTO> AddVideoComment(ReplyDTO replyDTO)
{
     List<ReplyDTO> replyList = new List<ReplyDTO>();
     replyList = VideoCommentList();
     replyList.Add(replyDTO);
     HttpRuntime.Cache.Insert("videoComment", replyList, null, Cache.NoAbsoluteExpiration, TimeSpan.FromDays(14));

     if (replyList.Count > 8)
     {
          replyList = replyList.OrderByDescending(x => x.DateCreated).Take(8).ToList();
     }
     else
     {
          replyList = replyList.OrderByDescending(x => x.DateCreated).ToList();
     }
     return replyList;
}

Ответы [ 5 ]

7 голосов
/ 24 января 2012

Кэш ASP.net находится в памяти, поэтому, если ваш процесс IIS или пул приложений будут перезагружаться, он очистится. Вы можете проверить следующие вещи, которые могут вызвать утилизацию процесса

  • Если вы измените web.config, IIS завершит работу старого экземпляра и медленно перенесет трафик на новый экземпляр, при этом оперативная память будет перезагружена. Как проверить это : Вы можете обнаружить эту ситуацию, проверив AppDomain.IsFinalizingForUnload и зарегистрировав это во время обратного вызова.
  • Переработка пула приложений : в IIS существует конфигурация, согласно которой, если процесс IIS простаивает в течение определенного времени, он перезапускает его. Вы можете проверить это на сервере и увеличить это время или вообще отключить утилизацию.
  • У каждого процесса есть ограничение на объем памяти, который он может использовать, если вы добавляете слишком много объектов в память, это увеличивает потребление памяти IIS, а в критическое время ОС перезапускает процесс.

EDIT

В вашей программе вы добавляете элемент replyList в кеш, а затем выполняете операцию .Take(). Поскольку replyList является ссылочным объектом, если вы измените его, он также будет обновлен в кеше. Так что если в вашей программе, если вы делаете replyList == null, он обновит элемент в кеше.

Поэтому измените ваш код следующим образом и попробуйте

public static List<ReplyDTO> VideoCommentList()
{
    List<ReplyDTO> replyList = new List<ReplyDTO>();
    if (HttpRuntime.Cache["videoComment"] == null)
    {
        //Call to .Remove is not required
        //HttpRuntime.Cache.Remove("videoComment");
        HttpRuntime.Cache.Insert("videoComment", replyList, null,
                         Cache.NoAbsoluteExpiration, TimeSpan.FromDays(14));
    }
    else
    {
        //No need to check count > 8, Take will handle it for you
        replyList = ((List<ReplyDTO>)HttpRuntime.Cache["videoComment"])
                        .OrderByDescending(x => x.DateCreated)
                        .Take(8).ToList();
    }
    return replyList;
}

public static List<ReplyDTO> AddVideoComment(ReplyDTO replyDTO)
{
    //Read from cache
    List<ReplyDTO> replyList = ((List<ReplyDTO>)HttpRuntime.Cache["videoComment"]);
    if(replyList == null)
        replyList = VideoCommentList();
    replyList.Add(replyDTO);
    HttpRuntime.Cache.Insert("videoComment", replyList, null, Cache.NoAbsoluteExpiration, TimeSpan.FromDays(14));

    //Here you are creating a new list, and not referencing the one in the cache
    return replyList.OrderByDescending(x => x.DateCreated).Take(8).ToList();
}

ВАЖНОЕ ПРЕДЛОЖЕНИЕ

Если вы хотите проверить, когда и почему ваш объект удаляется из кэша, вы можете воспользоваться опцией CacheItemRemovedCallback при вставке. Используя этот аргумент и CacheItemRemovedReason , вы можете записать причину удаления объекта из кэша. Причины

  1. Удалено - Ваш код удалил элемент из кэша, вызвав метод Insert или Remove.
  2. Истек срок действия - Элемент удален из кэша, поскольку срок его действия истек.
  3. Недостаточно используется - Когда системе не хватает памяти, она освобождает память, удаляя элемент из кэша.
  4. DependencyChanged - Элемент удален из кэша, так как изменилась зависимость кэша, связанная с ним. (В вашем случае это недействительно)

Надеюсь, эта информация поможет вам.

1 голос
/ 26 января 2012

Чтобы отследить, ПОЧЕМУ ваш элемент удаляется из кэша, я бы рекомендовал использовать другую перегрузку метода HttpRuntime.Cache.Insert, который позволяет вам указать функцию обратного вызова CacheItemRemovedCallback.

Метод Cache.Insert (String, Object, CacheDependency, DateTime, TimeSpan, CacheItemPriority, CacheItemRemovedCallback)

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

Как и большинство других ответов, я подозреваю, что вашприложение перерабатывается / сбрасывается по любому количеству причин.Я думаю, что большинство приложений на рабочей машине перерабатывают по крайней мере один раз в день, особенно в среде общего хостинга.Поэтому я предполагаю, что ваши данные будут храниться в кэше не более одного дня.

0 голосов
/ 01 февраля 2012

В методе AddVideoComment () измените строки вставки элемента кэша на:

  HttpRuntime.Cache.Insert("videoComment", replyList, null, Cache.NoAbsoluteExpiration, TimeSpan.FromDays(14),CacheItemPriority.NotRemovable,null);

А в методе VideoCommentList () используйте:

       if (HttpRuntime.Cache["videoComment"] == null)
        {
            replyList = VideoCommentList(); 
            HttpRuntime.Cache.Insert("videoComment", replyList, null, Cache.NoAbsoluteExpiration, TimeSpan.FromDays(14),CacheItemPriority.NotRemovable,null);
        }

Нет необходимости использоватьHttpRuntime.Cache.Remove("videoComment"); как HttpRuntime.Cache.Insert( заменит существующий элемент кэша.

Приветствия, DeveloperConcord

0 голосов
/ 30 января 2012

Ваши объекты кэша могут быть обрезаны по нескольким причинам ...

AppDomain recycle. Давление памяти. Краш. Использование веб-сада. Балансировки нагрузки. и так далее ...

Этот пост должен прояснить немного больше ...

http://blogs.msdn.com/b/praveeny/archive/2006/12/11/asp-net-2-0-cache-objects-get-trimmed-when-you-have-low-available-memory.aspx

0 голосов
/ 24 января 2012

Кэш находится в памяти и истекает, когда ваше приложение перезагружается. Я предполагаю, что вы оцениваете это на компьютере разработчика, где либо низкий объем трафика, либо ваши изменения в файле приводят к перезагрузке приложения.

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