Как удалить просроченные элементы из кеша?

У меня есть симпатичный маленький класс, который действует как кеш. У каждого элемента есть срок действия TimeSpan или DateTime. Каждый раз, когда делается попытка доступа к элементу в кэше, срок действия элемента проверяется, и, если он истек, элемент удаляется из кеша и ничего не возвращается.

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

Какая хорошая методология удаления таких элементов из кеша?

Должен ли я иметь фоновый поток, бесконечно перечисляющий каждый элемент в кеше, чтобы проверить, истек ли он?

Это кеш фиксированного размера? Если это так, я не вижу проблем с сохранением элементов в кеше.

Ryan Guest 26.09.2008 23:36
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
1
1 853
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Вы можете реализовать стратегию LRU (Least Recently Used), сохраняя ваши элементы отсортированными по времени доступа, когда новый элемент вставляется в кеш и, кеш заполнен, вы исключили элемент, который находится последним в этом списке. См. Алгоритмы кеширования в Википедии.

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

Вы также можете при любом изменении кеша (повторно) запустить таймер с интервалом, установленным на ближайшую временную метку истечения срока. Это не будет точным до миллисекунд и будет зависеть от работы насоса сообщений, но не требует больших ресурсов.

Ответ Харальда Шейриха лучше, если вы не возражаете, что объекты торчат вечно, когда кеш не обновляется.

Вы можете очистить подходящие старые элементы из кеша при первом доступе через 1 минуту после последней очистки элементов.

private DateTime nextFlush;
public object getItem(object key)
{
  DateTime now = DateTime.Now
  if (now > nextFlush)
  {
    Flush();
    nextFlush = now.AddMinutes(1)
  }
  return fetchItem(key);
}
Ответ принят как подходящий

По моему опыту, поддержание настраиваемого механизма кэширования стало для меня труднее, чем оно того стоило. Есть несколько библиотек, которые уже решили эти проблемы. Я бы предложил использовать один из них. Популярной в .Net является Enterprise Library, хотя у меня ограниченный опыт работы с ее возможностями кэширования.

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

Лучший код - это отсутствие кода. Вместо этого используйте кеш ASP.NET. Вы можете ссылаться на него как на System.Web.HttpRuntime.Cache в любом приложении, а не только в веб-приложениях.

Что, если сборка использует HttpRuntime.Cache в двух разных местах? У них один и тот же кеш, верно? В этом случае, к сожалению, это не сработает. Он уже используется, поэтому я не могу гарантировать, что мои предметы не будут удалены.

core 03.10.2008 04:35

Я не понимаю вашего комментария. Для каждого домена приложения существует один объект HttpRuntime.Cache. Если вы вставляете элементы в кеш в два разных места, вы должны использовать разные ключи - это верно для любого решения. Вы можете уточнить?

Joe 03.10.2008 14:55

Текущая альтернатива, если вы можете использовать структуру 4.0, - это ПамятьКэш. Это нарушает зависимость от ASP.Net, и у вас может быть несколько экземпляров, но требуется полная структура 4.0.

Kevin Pullin 20.02.2011 08:36

Другие вопросы по теме