2009-04-09 7 views
2

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

ответ

3

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

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

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

6

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

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

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

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

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

6

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

This search on google links to several resources about this.

+3

использование MemoryCache вместо http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache(v=vs.100).aspx см: HTTP: // StackOverflow .com/a/793720/303290 tl; dr: «если объекты Cache используются вне ASP.NET, системная память, зарезервированная для объектов Cache, не будет выпущена» – mbx

Смежные вопросы