2010-11-11 9 views
22

La clase StreamReader tiene un método de cierre y eliminación. Quiero saber qué método llamar para limpiar todos los recursos.cerrar o eliminar

Si utilizo el uso de bloque, creo que llamará a su método de eliminación. ¿Será suficiente para limpiar todos los recursos.

+1

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

Respuesta

22

El bloque using llamará al Dispose() en la instancia StreamReader. En general, si un tipo es IDisposable, debe ponerlo en el alcance using.

EDIT: Si nos fijamos en la implementación de Close()StreamReader usando Reflector, verá que está llamando Dispose(true). Por lo tanto, si no está utilizando el alcance using, llamar al Close() manualmente sería lo mismo que llamar al Dispose() en este caso particular.

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

cerrar llamadas disponer (verdadero), ¿usará block también call dispose (true)? – user496949

+0

Sí, lo hará ... –

+0

Esto explica por qué si tiene un código dentro de un 'using' con una llamada a' Close() ', al ejecutar el Análisis de código de Visual Studio obtendrá' CA2202 \t No elimine objetos varias veces' - porque 'Close()' ya dispone, y 'using' eventualmente tratará de eliminar el objeto, de nuevo. Me pregunto, entonces ... por qué no enfrentamos 'System.ObjectDisposedException'. – Veverke

1

El bloque de uso es todo lo que necesita.

+0

El uso garantizará la eliminación de llamadas. ¿Es lo mismo que llamar cerca? – user496949

+0

disponer cerrará implícitamente la secuencia –

16

Eliminar es suficiente y es esencial, ya que llamará a Cerrar por sí mismo y realizará más cosas que Cerrar no funcionará.

Usar el bloque es una forma elegante de disponer, así que sí, úselo siempre que sea posible.

+0

¿No es al revés, es decir. cerrar llamará a disponer? –

+0

@Backwards_Dave no, será un grave error que un objeto se deshaga de sí mismo. Es posible que aún desee utilizar la instancia después de cerrarla. –

+3

En la clase TextReader (el padre de StreamReader), la implementación de los métodos 'Close()' y 'Dispose()' es idéntica y llama a 'Dispose (true) '. En la clase StreamReader, 'Close()' llama al reemplazado 'Dispose (true)' que elimina el objeto. Por lo tanto, en este caso, es correcto decir que 'Close' llama a' Dispose'. –

0

Si desea más información sobre using, echar un vistazo aquí

Using

Presupuesto de sitio:

La instrucción using permite al programador para especificar cuando los objetos que los recursos de uso deben liberar ellos. El objeto provisto al uso de la declaración debe implementar la interfaz IDisposable . Esta interfaz proporciona el método Dispose, que debe liberar los recursos del objeto.

0

Parece haber cierta preocupación acerca de si Dispose realmente hace su trabajo correctamente.

Esencialmente - puede estar bastante seguro de que nada en el BCL (Base Class Library) que implementa IDisposable será poner en orden a sí misma correctamente cuando se llama disponer - por ejemplo, cuando una declaración utilizando sale del ámbito.

Si hubiera problemas con las transmisiones que no se cierran, ya se habrían recogido; puede confiar en IDisposable. Es cuando está utilizando otras bibliotecas que confía en la implementación Dispose.

1

Utilizar Eliminar a través de un bloque de uso para garantizar que se realice la limpieza.

Utilice Cerrar si finaliza con el objeto considerablemente antes de que finalice el uso del bloque, para que sea lo más rápido posible al liberar recursos.

Por lo tanto, ambos trabajarán mano a mano, aunque este último puede ser redundante si se llega al final del bloque en unos nanosegundos de todos modos.

3

Todos sabemos System.IO.StreamReader no es la única clase .NET 4.0+ que implementa IDisposable y un método Close(). Para el caso de StreamReader en esta pregunta, el código fuente muestra que la clase base TextReader.Close(), TextReader.Dispose() ambos ejecutan las mismas líneas de código. También puede ver en el código que TextReader.Dispose() es la implementación para cuando llama al StreamReader.Dispose() (porque StreamReader no anula la firma de sobrecarga de método de Dispose).

Así una llamada a StreamReader.Dispose() se ejecutará this inherited line of code, que llama al método sustituto protegidos StreamReader.Dispose(disposing: true) y también lo hará StreamReader.Close() llamada StreamReader.Dispose(disposing: true). Por lo tanto, para el caso de StreamReader, Close() y Dispose() sucede que se ejecutan las mismas líneas de código.

Una respuesta más general, no específica de la clase a la pregunta de ¿Cerrar() o desechar()?, podría ser que tenga en cuenta que Microsoft tiene bastante claro documentation on implementing IDisposable and the Dispose pattern. Una lectura rápida es suficiente para mostrarle que implementar un método Close() no es un requisito del patrón Dispose.

iho el motivo para encontrar el método Close() en tantas clases que implementan IDisposable, es el resultado de una convención, no un requisito.

alguien comentó

Close and Dispose - which to call?

Un ejemplo de otra clase que implementa IDisposable con el patrón Dispose, y tiene un método Close(). ¿Funciona Close() el mismo código que Dispose() en este caso? No he visto el código fuente, pero diría que no necesariamente.

Cuestiones relacionadas