2010-10-29 7 views
5

Digamos que tengo que mostrar algunos gráficos con algún control. Pero habrá tres imágenes conmutadas en función de alguna condición. Se agrega tres mapas de bits en el archivo de recursos.Obtener imagen de ResourceManager GetObject: ¿llamarla siempre o almacenar el resultado?

Por lo tanto, los recupero al llamar a ResourceManager.GetObject.

La cuestión es que, en caso de ser:

  1. Cada vez que tengo que cambiar la imagen, que llama a GetObject para conseguirlo y asignar al control o
  2. aguantar el resultado de GetObject para cada imagen al principio, de modo que solo habrá 3 llamadas al GetObject. Asignar imagen de mis variables en su lugar.

Haciendo 1) parece producir una gran cantidad de control de GC cuando se lo visualiza con CLR Profiler. Esperando saber cualquier efecto secundario malo de 2).

Muchas gracias.

Respuesta

5

Cada llamada a GetObject leerá la imagen del ensamblaje y la cargará en un objeto Bitmap.

Llamarlo muchas veces generará una sobrecarga significativa; deberías almacenar las imágenes.

1

El MSDN documentation indica que el valor del recurso es devuelto por ResourceManager.GetObject. Como parece que los mapas de bits individuales no cambian en el tiempo de ejecución, el único inconveniente que veo al acercarme al n. ° 2 es que su espacio de memoria será un poco más grande.

3

Una cosa más para señalar acerca de llamar a "ResourceManager.GetObject" cada vez que necesita utilizar una imagen de Resources es que parece crear un nuevo Windows Handle cada vez. En su caso, probablemente no sea gran cosa, pero si tuviera que aferrarse a ellos por un tiempo como nosotros, podría causar un problema.

Teníamos un DataGridView en el que estábamos empujando imágenes de los Recursos a diferentes campos de la grilla y cuando esa grilla se elevaba a más de 3000 filas realmente excedíamos el máximo permitido de Windows para un programa de 32 bits.

El error apareció al azar Excepciones de argumento con el mensaje "El parámetro no es válido". Nos llevó algunas horas pensar que teníamos una pérdida de memoria pero finalmente encontramos que cargamos esta GUI con esa cuadrícula que las aplicaciones manejan pasaron de 700-1000 a más de 10K antes de que siquiera terminara de cargarse y se bloquee todo el programa y no se pudo recuperar. Así que recomiendo la opción 2 aquí.

2

También he implementado el "read once then store in variable" concept en mis clases.

Para dar un ejemplo, aquí es un extracto de mi código:

internal static class MyResourcesHolder 
{ 
    private static Image _i1; 
    private static Image _i2; 
    private static Image _i3; 
    private static Image _i4; 
    private static Image _i5; 

    public static Image MyImage01 => _i1 ?? (_i1 = Resources.MyImage01); 
    public static Image MyImage02 => _i2 ?? (_i2 = Resources.MyImage02); 
    public static Image MyImage03 => _i3 ?? (_i3 = Resources.MyImage03); 
    public static Image MyImage04 => _i4 ?? (_i4 = Resources.MyImage04); 
    public static Image MyImage05 => _i5 ?? (_i5 = Resources.MyImage05); 
} 

Tal vez esto ayude a alguien algún día.

Cuestiones relacionadas