C # Коллекция, чьи предметы истекают - PullRequest
2 голосов
/ 09 апреля 2009

Я пишу консольное приложение на C #, в котором я хочу кэшировать определенные элементы в течение заранее определенного времени (скажем, 1 час). Я хочу, чтобы элементы, добавленные в этот кеш, автоматически удалялись после истечения срока их действия. Есть ли встроенная структура данных, которую я могу использовать? Помните, что это консольное приложение, а не веб-приложение.

Ответы [ 4 ]

6 голосов
/ 09 апреля 2009

Это уже в BCL. Его просто нет там, где вы ожидаете его найти: вы можете использовать System.Web.Caching и из других приложений, не только в ASP.NET.

Этот поиск в Google ссылается на несколько ресурсов по этому поводу.

6 голосов
/ 09 апреля 2009

Вам действительно нужно, чтобы они были удалены из кэша в то время? Или только то, что будущие запросы к кешу для этого элемента должны возвращать нуль через заданное время?

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

Создать такой класс тривиально.

class CachedObject<TValue> 
{ 
 DateTime Date{get;set;}
 TimeSpan Duration{get;set;}
 TValue Cached{get;set;}
}

class Cache : Dictionary<TKey,TValue>
{
  public new TValue this(TKey key)
  {
    get{
    if (ContainsKey(key))
    {
       var val = base.this[key];
       //compare dates
       //if expired, remove from cache, return null
       //else return the cached item.
    }
    }

    set{//create new CachedObject, set date and timespan, set value, add to dictionary}

  }
3 голосов
/ 09 апреля 2009

Включите свойство ExpirationDate в объект, который вы будете кэшировать (вероятно, обертку вокруг вашего реального объекта), и задайте для него срок действия в конструкторе через час. Вместо удаления элементов из коллекции, получите доступ к коллекции с помощью метода, который отфильтровывает просроченные элементы. Или создайте собственную коллекцию, которая делает это автоматически. Если вам действительно нужно удалить элементы из кэша, ваша пользовательская коллекция может вместо этого очищать элементы с истекшим сроком при каждом вызове одного из его участников.

3 голосов
/ 09 апреля 2009

Я не знаю ни одного объекта в BCL, который бы делал это, но я писал подобные вещи раньше.

Вы можете сделать это довольно легко, просто включив System.Threading.Timer в свой класс кэширования (без зависимостей web / winforms) и сохраняя время истечения (или последнего использования) ваших объектов. Просто проверяйте таймер каждые несколько минут и удаляйте объекты, срок действия которых вы хотите истечь.

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

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