2010-11-11 11 views
22

La classe StreamReader dispone sia del metodo close che di quello di eliminazione. Voglio sapere quale metodo chiamare per ripulire tutte le risorse.chiudere o smaltire

Se si utilizza l'utilizzo del blocco, penso che chiamerà il suo metodo di smaltimento. Sarà sufficiente per ripulire tutte le risorse.

+1

http://stackoverflow.com/q/61092/102112 – Alex

risposta

22

Il blocco using chiamerà Dispose() nell'istanza StreamReader. In generale, se un tipo è IDisposable, è necessario inserirlo nello scope using.

EDIT: Se si guarda alla Close() attuazione StreamReader utilizzando Reflector, vedrete che si sta chiamando Dispose(true). Pertanto, se non si utilizza l'ambito using, chiamare manualmente Close() equivale a chiamare Dispose() in questo caso particolare.

protected override void Dispose(bool disposing) 
{ 
    try 
    { 
     if ((this.Closable && disposing) && (this.stream != null)) 
     { 
      this.stream.Close(); 
     } 
    } 
    finally 
    { 
     if (this.Closable && (this.stream != null)) 
     { 
      this.stream = null; 
      this.encoding = null; 
      this.decoder = null; 
      this.byteBuffer = null; 
      this.charBuffer = null; 
      this.charPos = 0; 
      this.charLen = 0; 
      base.Dispose(disposing); 
     } 
    } 
} 
+0

chiudi chiamate dispose (true), utilizzerà il blocco anche chiamata dispose (true)? – user496949

+0

Sì, lo sarà ... –

+0

Questo spiega perché se si ha codice all'interno di un 'using' con una chiamata a' Close() ', quando si esegue l'analisi del codice di Visual Studio si ottiene' CA2202 \t Non disporre oggetti più volte ' - poiché 'Close()' dispone già, e 'using' alla fine tenterà di eliminare l'oggetto, di nuovo. Mi chiedo, allora ... perché non ci troviamo davvero di fronte a "System.ObjectDisposedException". – Veverke

1

Il blocco di utilizzo è tutto ciò che serve.

+0

L'utilizzo garantisce la chiamata. È lo stesso di chi chiama da vicino? – user496949

+0

dispose implicherà chiudere il flusso –

16

Il dispose è sufficiente ed è essenziale, poiché chiamerà Chiudi tutto da solo ed eseguirà più cose che Chiudi non farà.

L'utilizzo del blocco è un modo elegante di disporre di tale sì, utilizzarlo quando possibile.

+0

Non è il contrario, vale a dire. chiudi chiamerà dispose? –

+0

@Backwards_Dave no, questo sarà un grave errore per un oggetto che si disponga. Potresti comunque voler utilizzare l'istanza dopo averla chiusa. –

+3

Nella classe TextReader (il genitore di StreamReader), l'implementazione dei metodi 'Close()' e 'Dispose()' è identica e chiama 'Dispose (true)'. Nella classe StreamReader, 'Close()' chiama 'Dispose (true)' sovrascritto che dispone l'oggetto. Pertanto, in questo caso, è corretto dire che 'Close' chiama' Dispose'. –

0

Se desiderate maggiori informazioni su using, date un'occhiata qui

Using

Citazione da un sito:

L'istruzione using permette al programmatore per specificare quando gli oggetti che utilizzare le risorse dovrebbe rilasciare loro. L'oggetto fornito all'utilizzo della dichiarazione deve implementare l'interfaccia IDisposable ID. Questa interfaccia fornisce il metodo Dispose, che dovrebbe rilasciare le risorse dell'oggetto.

0

Sembra esserci qualche preoccupazione sul fatto che lo Dispose svolga correttamente il proprio lavoro.

In sostanza - si può essere abbastanza certi che nulla nella (libreria di classi base) BCL che implementa IDisposable sarà riordinare se stesso correttamente quando Dispose viene chiamato - come quando un'istruzione using esce dallo scope.

Se ci fossero problemi con i flussi che non venivano chiusi, sarebbero stati prelevati da ora - ci si può fidare di IDisposable. È quando si utilizzano altre librerie basate sull'implementazione Dispose.

1

Utilizzare Dispose tramite un blocco di utilizzo per garantire che si verifichi la pulizia.

Utilizzare Chiudi se si finisce con l'oggetto considerevolmente prima della fine del blocco di utilizzo, per essere il più tempestivo possibile nel rilasciare risorse.

I due funzioneranno quindi mano nella mano, sebbene quest'ultimo possa essere ridondante se si raggiungerà comunque la fine del blocco in pochi nanosecondi.

3

Sappiamo tutti che System.IO.StreamReader non è l'unica classe .NET 4.0+ che implementa IDisposable e un metodo Close(). Nel caso di StreamReader in questa domanda, il codice sorgente mostra che la classe base TextReader.Close(), TextReader.Dispose() esegue entrambe le stesse righe di codice. È inoltre possibile vedere nel codice che TextReader.Dispose() è l'implementazione per quando si chiama StreamReader.Dispose() (poiché non sovrascrive la firma di sovraccarico del metodo di Dispose).

Quindi, una chiamata a StreamReader.Dispose() verrà eseguito this inherited line of code, che chiama il metodo protected override StreamReader.Dispose(disposing: true) e così sarà chiamata StreamReader.Close()StreamReader.Dispose(disposing: true). Quindi per il caso di StreamReader, Close() e Dispose(), è necessario eseguire le stesse righe di codice.

Una risposta più generale, non specifica della classe alla domanda di Close() o Dispose()?, potrebbe essere notare che Microsoft ha abbastanza chiaro documentation on implementing IDisposable and the Dispose pattern. Una lettura veloce è sufficiente per mostrare che l'implementazione di un metodo Close() non è un requisito del modello Dispose.

imho il motivo per trovare il metodo Close() su così tante classi che implementano IDisposable, è il risultato di convenzione, non requisito.

Qualcuno commentato

Close and Dispose - which to call?

Un esempio di un'altra classe che implementa IDisposable con il pattern Dispose, e ha un metodo Close(). Close() esegue lo stesso codice di Dispose() in questo caso? Non ho guardato il codice sorgente, ma direi non necessariamente.

Problemi correlati