2010-10-29 4 views
5

Diciamo che devo mostrare alcuni elementi grafici su qualche controllo. Ma ci saranno tre immagini commutate in base ad alcune condizioni. Tre bitmap sono stati aggiunti nel file di risorse.Acquisizione immagine da ResourceManager GetObject - Chiamarlo ogni volta o memorizzare il risultato?

Quindi, li recupero chiamando ResourceManager.GetObject.

La questione è che, dovrebbe essere:

  1. Ogni devo cambiare immagine, chiamo GetObject per farlo e assegnare al controllo o
  2. tenere il risultato di GetObject per ogni immagine all'inizio, in modo che ci siano sempre solo 3 chiamate a GetObject. Assegna invece l'immagine dalle mie variabili.

Fare 1) sembra produrre molto handle GC se visualizzato con CLR Profiler. Sperando di conoscere qualsiasi effetto collaterale negativo di 2).

Grazie mille.

risposta

5

Ogni chiamata a GetObject leggerà l'immagine dall'assieme e la caricherà in un oggetto Bitmap.

Chiamarlo più volte creerà un sovraccarico significativo; dovresti conservare le immagini.

1

Il MSDN documentation indica che il valore della risorsa viene restituito da ResourceManager.GetObject. Dal momento che sembra che le singole bitmap non cambino in fase di esecuzione, l'unico lato negativo che vedo per approccio # 2 è che il tuo footprint di memoria sarà un po 'più grande.

3

Solo un'altra cosa da segnalare chiamata "ResourceManager.GetObject" ogni volta che è necessario utilizzare un'immagine da Risorse è che sembra creare un nuovo handle di Windows ogni volta. Nel tuo caso probabilmente non è un grosso problema, ma se dovessi trattenerli per un po 'come quello che abbiamo fatto potrebbe causare un problema.

Avevamo un DataGridView che stavamo spingendo le immagini da Risorse in diversi campi della griglia e quando quella griglia si alzò su 3000 righe in realtà stavamo superando le maniglie di Windows massime consentite per un programma a 32 bit.

L'errore è apparso su un argomento casuale Eccezioni con messaggio "Il parametro non è valido". Ci sono volute alcune ore pensando che avessimo una perdita di memoria, ma alla fine abbiamo trovato quello che abbiamo caricato questa GUI con quella griglia, le maniglie delle applicazioni sono passate da 700-1000 a oltre 10K prima che finisse di caricare e manderebbe in crash l'intero programma e non potrebbe essere ripristinato. Quindi raccomando l'opzione 2 qui.

2

Ho anche implementato il "read once then store in variable" concept nelle mie classi.

per fare un esempio, ecco un estratto dal mio codice:

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); 
} 

Forse questo aiuta qualcuno un giorno.

Problemi correlati