2012-04-11 5 views
5

Per esempio Ho un metodoAutodisposing oggetti

SomeMethod(Graphics g) 
{ 
    ... 
} 

Se voglio chiamare questo metodo in modo

SomeMethod(new Graphics()) 

sarà il mio oggetto Graphics essere autodisposed o devo chiamare g.Dispose() manualmente alla fine del il metodo?

SomeMethod(Graphics g) 
{ 
    ... 
    g.Dispose(); 
} 
+4

Oltre a "no", il metodo deve anche * non * essere responsabile per lo smaltimento dell'oggetto grafico. È importante che la vita degli oggetti grafici sia gestita in un unico posto, vale a dire che deve essere smaltita nella stessa classe in cui è stata creata. Disporre di un oggetto in un punto indefinito, lungo lo stack di chiamate, rende il codice difficile da comprendere e mantenere, e potrebbe facilmente portare a errori successivi. – MattDavey

risposta

7

oggetti monouso non ottenere autodisposed (più vicino che può arrivare a che sta attuando un Finalizer che chiama Dispose se necessario). Devi farlo manualmente chiamando Dispose() o usandolo con un blocco using.

Se si vuole auto smaltire l'oggetto, si potrebbe fare questo:

using (var g = new Graphics()) { 
    SomeMethod(g); 
} 

Il blocco utilizzando assicura che il metodo Dispose() viene chiamato automaticamente non appena il blocco estremità (quindi in questo caso, dopo SomeMethod restituisce o genera un'eccezione).

Nota: è necessario disporre l'oggetto nel punto in cui è stato creato, se possibile. Prendere un oggetto valido e smaltirlo all'interno del metodo potrebbe causare confusione.

Grafica e probabilmente la maggior parte se non tutte le classi BCL che implementano questa interfaccia chiameranno anche Dispose() quando viene chiamato Finalizer. Questo fa parte di un'implementazione corretta di IDisposable. Tuttavia non si sa mai quando viene chiamato il finalizzatore e non si dovrebbe fare affidamento su questi dettagli di implementazione se si desidera che l'oggetto venga eliminato in modo deterministico.

+1

Nel mio esempio sopra, l'oggetto grafico sarà autodisposto o no? –

+0

No. Vedi la mia modifica. – Botz3000

+0

Aspetta, stai dicendo che il GC non chiamerà 'Dispose' quando l'oggetto è finalizzato? (Data una corretta implementazione di 'IDisposable') – leppie

3

probabilmente si dovrebbe utilizzare un'istruzione using

using (var graphicsObject = new Graphics()) { 
    SomeMethod(graphicsObject); 
} 

L'oggetto verrà automaticamente essere smaltiti alla fine del l'istruzione using, anche se si verifica un'eccezione.

2

check Graphics Class

public sealed class Graphics : MarshalByRefObject, 
    IDeviceContext, IDisposable 

Esso implementa l'interfaccia IDisposable, quindi se si utilizza l'istruzione using con l'oggetto Graphics allora sarà automaticamente eliminato.

Nel tuo esempio

SomeMethod(Graphics g) 
     { 
     ... 
     g.Dispose(); 
     } 

che sarà disposto con il g.Dispose, ma le migliori prassi è using dichiarazione.

esempio:

using (Graphics g = this.CreateGraphics()) 
{ 
//Do some graphics operation. 
} 
4

Il modo corretto di lavorare con oggetti monouso è di metterli in using blocchi:

using (var g = new Graphics()) { 
    SomeMethod(g); 
} 

Quando l'esecuzione lascia il blocco using il Graphics sia correttamente disposto anche se un l'eccezione è lanciata.

Tuttavia, se non smaltire l'oggetto sia esplicitamente o implicitamente utilizzando un blocco using dell'oggetto sarà ancora ottenere disposta quando è garbage collection (assumendo che il finalizzatore chiama correttamente il Dispose come dovrebbe). Quando ciò accade non è sotto il tuo controllo ed è per questo che devi assicurarti che gli oggetti usa e getta siano disposti correttamente non appena non sono più necessari per liberare le risorse rivendicate dagli oggetti.

2

Nell'esempio non è necessario disporre di un oggetto assegnato come argomento. Questo non è consigliabile perché quell'oggetto potrebbe essere usato al di fuori del tuo metodo. Lo smaltimento degli oggetti di utilità dovrebbe (di solito) avvenire nello stesso metodo in cui lo si crea. Eccezione per oggetti di classe o oggetti di stato.

Come in altre risposte, utilizzare using per creare e smaltire un oggetto. Questo è richiesto solo da oggetti che utilizzano risorse preziose come la connessione al database. Detto questo dovresti sempre chiamare lo Dispose() (esplicitamente o per using) se l'oggetto lo implementa perché significa che usa quantità non gestite o grandi quantità di risorse.

Tutti gli oggetti .NET Framework che non si chiama Dispose su (in entrambi i casi) verranno automaticamente convertiti in da Garbage Collector. L'implementazione corretta dell'interfaccia IDisposable dovrebbe avere un distruttore/finalizzatore che chiama Dispose. Questo per assicurarsi che le preziose risorse non vengano perse solo a causa del codice errato. Le tue risorse saranno rilasciate molto più tardi ma lo farebbero e questo è importante. In questo modo vengono implementate tutte le classi usa e getta in .NET e in che modo tutte le classi devono implementare IDisposable.

Il codice dovrebbe essere simile a questa:

using(Graphics g = new Graphics()) 
{ 
    SomeMethod(g) 
    { 
     ... 
    } 
} 

Controllare this per le raccomandazioni di Microsoft su IDisposable.Dispose metodo.

Problemi correlati