Eliminar el elemento más antiguo de un diccionario

Estoy trabajando con una aplicación WPF encargada de mostrar una gran cantidad de archivos de mapa de bits. En el futuro planeo implementar una solución usando gráficos vectoriales, pero por ahora tengo este problema:

Para minimizar el tiempo que mi aplicación lee archivos del disco, creé un Dictionary<string, BitmapImage> (donde cadena es la ruta del archivo de la imagen) para contener las imágenes utilizadas más recientemente. Si se solicita una imagen que se vio recientemente, el programa la obtiene del Dictionary en lugar de desde el disco. Sin embargo, a medida que aumenta el número de imágenes visualizadas, también lo hace la cantidad de RAM utilizada por el programa. Así que mi idea era contener una cantidad limitada de imágenes y, a medida que se cargaba una nueva desde el disco, sobrescribía la más antigua de mi Dictionary.

¿Cómo haría esto de la mejor manera posible? He investigado el uso de un SortedDictionary pero no sé cómo escribir un IComparer como ni el keys or items tener información sobre la hora / orden en que se agregaron.

Mantendría un separado SortedDictionary<DateTime, string> con un DateTime IComparer ser una solución sensata? De esa manera, cuando se agrega un nuevo archivo, se puede encontrar la ruta al archivo agregado más antiguo y hacer coincidir con la imagen correcta en mi Dictionary. Sin embargo, este tipo de se siente como una solución demasiado avanzada. ¿Alguna solución incorporada o pasada por alto?

preguntado el 08 de noviembre de 11 a las 09:11

4 Respuestas

Suena como si quisieras un caché de uso menos reciente (LRU) ("descarta primero los elementos usados ​​menos recientemente"). Hay algunas implementaciones flotando en la web:

respondido 08 nov., 11:13

Usaré el de Bob Rossney. Mejor usar uno bueno que hacer uno mediocre por mi cuenta; P ¡Gracias! - Tina

SI está en .NET 4, hay un mecanismo de caché incorporado; para obtener un tutorial, consulte http://msdn.microsoft.com/en-us/library/dd997362.aspx

Le permite establecer condiciones cuando el elemento almacenado en caché respectivo se descarta, etc. y permite una devolución de llamada en caso de que un elemento esté a punto de ser eliminado (ver http://msdn.microsoft.com/en-us/library/system.runtime.caching.cacheitempolicy.aspx).

Puede implementar la política de almacenamiento en caché que describió (se llama LRU: uso menos reciente) mediante el uso CacheItemPolicy.SlidingExpiration.

respondido 08 nov., 11:13

Gracias, pero estamos en 3.5. ¡Sin embargo, lo tendré en cuenta para futuras aventuras! - Tina

Le sugiero que se lo facilite y cree un diccionario en un diccionario.

Por ejemplo:

Dictionary<DateTime, Dictionary<string, Image>> SortedByDate;

No estoy seguro de cómo y si un diccionario ordenado ordena las fechas correctamente, pero si lo hace y la más antigua es igual a la última entrada, es bastante fácil eliminar esa entrada.

respondido 08 nov., 11:13

Sin embargo, esto ya no le permite buscar por ruta (cadena), ¿verdad? - ssube

¡Gracias, intentaré ese! De acuerdo a stackoverflow.com/questions/453124/… DateTime debería funcionar como clave. - Tina

@peachykeen ¡No pensé en eso! Lo investigaré más a fondo. - Tina

@peachykeen: si desea buscar la ruta, tendría sentido almacenar el diccionario interno en una segunda variable. - Andre Fly

@AndreFly Pero entonces tendrías varias veces para la misma ruta, que debería ser la misma imagen, y nuevamente frustra el propósito. Es necesario almacenar ambos, pero no puede indexar ambos de forma anidada. - ssube

Sugeriría contra un diccionario y, en su lugar, use una Lista con una clase personalizada que toma un mapa de bits, una cadena y una Fecha y hora, algo como:

public Class ImageLocation{
    public BitmapImage image;
    public string location;
    public DateTime timeLoaded;
}

Entonces puedes usar un List<ImageLocation> para almacenar sus imágenes. Ordénelos por timeLoaded y luego elimine el que tenga el DateTime más antiguo.

Es decir, si no va a utilizar la caché LRU por alguna razón.

Respondido 25 Abr '15, 23:04

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.