2009-10-15 17 views
6

In un programma VB.NET sto creando una nuova immagine bitmap, quindi chiamo Graphics.FromImage per ottenere un oggetto Graphics da disegnare sulla bitmap. L'immagine viene quindi visualizzata all'utente.Devo chiamare Graphics.Dispose()?

Tutti gli esempi di codice che ho visto chiamano sempre .Dispose() su oggetti Bitmap e Graphics, ma è necessario farlo quando nessuno dei due ha toccato i file sul disco? Ci sono altre risorse non gestite che questi oggetti potrebbero aver afferrato che non sarebbero state cancellate dal garbage collector?

risposta

5

Sì.

Chiamare sempre Dispose() su qualsiasi oggetto che implementa IDisposable. Gli handle GDI usati dagli oggetti grafici non sono gestiti e richiedono lo smaltimento una volta terminati.

La procedura ottimale consiste nel racchiudere un blocco using. Ci sono state diverse domande SO su questo argomento, BTW.

+0

Siamo spiacenti se questo è un duplicato. Non ho visto nulla che riguardasse questo caso specifico ed ero curioso di sapere quali (eventuali) risorse non gestite sarebbero state usate in questo caso. – alnorth29

1

Sì, è necessario chiamare Dispose. Non è legato al contatto con il disco; è correlato all'utilizzo di risorse non gestite che devono essere rilasciate correttamente nel sistema operativo. Nel caso dell'oggetto Graphics, suppongo che allochi gli handle di contesto del dispositivo che dovrebbero essere rilasciati quando non sono più necessari.

6

Avvolgere in un utilizzando la dichiarazione per l'ambito in cui è necessario. Quindi non ti preoccupare in modo esplicito chiamando Dispose()

Pseudocodice:

using(new Graphics() = Graphics.FromImage) 
{ 
    //Magic happens... 
} 
1

La regola con Dispose() è che se si è creato un oggetto che è IDisposable, quindi si suppone di chiamarla. Il modo migliore è all'interno di un blocco using o finally.

È possibile che non sia necessario eseguirlo, ma Dispose() lo deciderà.

Se si ottiene un oggetto ma non si chiama il costruttore, è necessario controllare la documentazione per il metodo che lo ha restituito per vedere se prevede di chiamare Dispose() o lo farà.

+0

Per essere precisi, l'uso corretto di 'using' (vedere altre risposte) implica implicitamente' Dispose', quindi non è necessario chiamarlo da soli. – ToolmakerSteve

0

Graphics implements IDisposable, quindi è necessario chiamare Dispose per garantire la pulizia delle risorse non gestite.

Le risorse non gestite non vengono gestite dal garbage collector, quindi devono essere gestite manualmente. Questo in genere viene eseguito dal metodo Dispose() per fornire la pulizia in un momento preciso. Può anche essere gestito da un finalizzatore, ma in tal caso le risorse saranno utilizzate più a lungo del necessario.

Il modo più semplice per garantire che Dispose venga chiamato in tutti i casi è utilizzare il costrutto di utilizzo. Per esempio.

using(var g = Graphics.FromImage()) { 
    // use the resource 
} 
+0

"devono essere gestiti manualmente" non è strettamente vero come hai scritto un po 'più tardi. La corretta implementazione di "IDisposable" dovrebbe garantire la sicurezza anche senza disporre manuale (nel codice). –

+0

@MaciejDopieralski: Prenderò in considerazione qualsiasi cosa tu debba scrivere codice per essere un processo manuale.Se ti dimentichi di chiamare Dispose, la pulizia non avrà luogo. La raccolta di oggetti gestiti invece avviene automaticamente. –

+0

Se parli di classi proprie, allora sì, ma tutte le classi .NET 'IDisposable' vengono eliminate prima o poi anche se non chiami' Dispose' nel tuo codice. –

Problemi correlati