2011-06-27 9 views
14

muszę funkcję tak:Lista z timeout/wygasa zdolność

AddToList(txtName, timeExpire); 

to wygląda self-opisowy, obiekt zostanie automatycznie wygasa i usuwane z listy.

Nie mogłem sobie wyobrazić, jak to zrobić. Czy ktoś może mi dać wskazówkę?

+1

Nazywa się to 'cache'. – leppie

+3

clue: utwórz strukturę danych, która to zrobi – crashmstr

+0

Jeśli korzystasz z asp.net, klasy pamięci podręcznej zrobią to za ciebie. –

Odpowiedz

7

Możesz też wypróbować coś takiego.

Tworzenie niestandardowej klasy

public class Custom 
    { 
     string item; //will hold the item 
     Timer timer; //will hanlde the expiry 
     List<Custom> refofMainList; //will be used to remove the item once it is expired 

     public Custom(string yourItem, int milisec, List<Custom> refOfList) 
     { 
      refofMainList = refOfList; 
      item = yourItem; 
      timer = new Timer (milisec); 
      timer.Elapsed += new ElapsedEventHandler(Elapsed_Event); 
      timer.Start(); 
     } 

     private void Elapsed_Event(object sender, ElapsedEventArgs e) 
     { 
      timer.Elapsed -= new ElapsedEventHandler(Elapsed_Event); 
      refofMainList.Remove(this); 

     } 
    } 

Teraz można tworzyć List<Custom> i używać go. To przedmioty zostaną usunięte po upływie określonego czasu.

+0

Podobne rozwiązanie sprawdziło się doskonale. W moim przypadku stworzyłem singleton do przechowywania wartości buforowanych w ConncurrentDictionary. Następnie używam zdarzenia czasu, aby wyczyścić buforowane wartości co jakiś czas. Użyłem wygaśnięcia poślizgowego. –

+2

jak to podejście działałoby w apekcie asp.net działającym w IIS. Wierzę, że są komplikacje z licznikami uruchomionymi w iis? – Zapnologica

3

Musisz utworzyć obiekt, który będzie w stanie to zarządzać.

Pomyśl o tym, co będzie trzeba przechowywać w jednym elemencie. Zasadniczo dane (np. txtName) i czas wygaśnięcia. Oznacza to, że prawdopodobnie będziesz potrzebować klasy lub struktury, która ma tylko te 2 elementy.

Twoja klasa ExpiringList będzie listą tego typu.

Teraz masz swoją podstawową strukturę danych (kolekcja/lista ExpiringListItem), musisz pomyśleć o operacjach, które chcesz obsłużyć. Obecnie masz listę AddToList, inni prawdopodobnie to RemoveFromList, Clear i może iterować po wszystkich elementach.

Jedyną rzeczą unikatową dla twojego ExpiredList w porównaniu do normalnego List<T> jest to, że chcesz automatycznie usuwać wygasłe przedmioty. Dlatego sensownym jest, aby Twój ExpiringList zaimplementował interfejs IList<T> i wewnętrznie używał Listy prywatnej, możliwe, że twoja lista (i z konieczności Twoja klasa ExpiredListItem) będzie generyczna.

Trudna część, poza zrozumieniem i wdrażaniem dziedziczenia (naprawdę to osobne pytanie), polega na usuwaniu wygasłych przedmiotów.

Oznaczałoby to utworzenie metody w klasie, która iterowała (w odwrotnej kolejności) nad przedmiotami, porównując czas wygaśnięcia z bieżącym czasem i usuwanie wygasłych.

Interfejs można zaimplementować, wywołując odpowiednie metody na wewnętrznej liście.

W tym momencie możesz powiedzieć, że skończyłeś, ponieważ po prostu nazywasz tę metodę okresowo, aby upewnić się, że wszystkie wygasłe przedmioty zniknęły, zanim użyjesz pozycji na liście.

Może lepszym rozwiązaniem byłoby wywołanie tej metody przed uruchomieniem metody na wewnętrznej liście. W zależności od tego, jak wykorzystasz swoją listę, może to być przesada.

+1

W skrócie; Użyję stopera, aby okresowo sprawdzać wygasłe przedmioty. –

+0

@Nime, to by działało, lub możesz użyć sugestii w moim ostatnim akapicie (jeśli chcesz stworzyć klasę, która to zarządzała, zamiast jednej metody działającej na liście). –

21

Jeśli kierujesz na .NET 4 lub nowszy, użyj MemoryCache (lub wyprowadź niestandardową implementację z ObjectCache).

Przed 4, jeśli chcesz mieć pamięć podręczną w swojej aplikacji, możesz po prostu zaczepić System.Web.Cache i użyć jej w dowolnej aplikacji .NET. Nie miał on żadnych zależności od żadnego kodu "web", ale wymagał odniesienia do System.Web.dll. Wydawało się to dziwne (jak odniesienie do Microsoft.VisualBasic.dll z aplikacji C#), ale nie wpłynęło to negatywnie na twoją aplikację.

Wraz z nadejściem Client Profile, ważne stało się zerwanie zależności między kodem zorientowanym na komputery a kodem zorientowanym na serwer. Wprowadzono ObjectCache, aby programiści aplikacji (nie pewni twórców silverlight, wp7) mogli zerwać tę zależność i mogli kierować tylko na profil klienta.

+0

3.5 jeszcze. Będę pamiętać. –

11

Wystarczy szybkie przykładem odpowiedź będzie dało

Dodaj odwołanie do System.Runtime.Caching

MemoryCache cache = new MemoryCache("CacheName"); 

cache.Add(key, value, new CacheItemPolicy() 
          { AbsoluteExpiration = DateTime.UtcNow.AddSeconds(20) }); 

Następnie można sprawdzić, czy coś jest jeszcze w pamięci podręcznej, przechodząc

if (cache.Contains(key)) 

A jeśli chcesz, aby pamięć podręczna miała niski limit czasu, będziesz musiał zmienić czas odświeżania pamięci podręcznej za pomocą fajnego, małego hacka.

MemoryCache AbsoluteExpiration acting strange

+0

Czy otrzymujesz współbieżną pamięć podręczną pamięci? Zasadniczo C# 'ConcurrentDictionary' z funkcją wygasania? – Zapnologica

+2

@Zapnologica MemoryCache jest całkowicie bezpieczny dla wątków, zobacz tę odpowiedź: http://stackoverflow.com/a/6738179/606554 – elbweb