2010-12-16 16 views
16

Tengo una clase que esencialmente envuelve un flujo para leer/escribir, pero se espera que ese flujo sea administrado por el consumidor de esa clase. Para facilitar el uso, uso las clases StreamReader y StreamWriter para realizar operaciones de E/S en la transmisión. Normalmente envolvería el lector y el escritor en los bloques using, pero quiero evitar cerrar el lector y el escritor porque al hacerlo también se cierra el flujo subyacente y tengo que mantenerlo abierto.¿Está bien no cerrar StreamReader/StreamWriter para mantener abierta la secuencia subyacente?

¿Es seguro en términos de gestión de memoria/recursos no cerrar un StreamReader/StreamWriter si espero que el emisor gestione el Stream subyacente? ¿Serán el lector y el escritor recolectados basura cuando la transmisión se cierre explícitamente en otro lugar?

public class Wrapper 
{ 
    private Stream _underlyingStream; 
    public Wrapper(Stream underlyingStream) 
    { 
     _underlyingStream = underlyingStream; 
    } 

    public string GetValue() 
    { 
     _underlyingStream.Seek(0, SeekOrigin.Begin); 
     var reader = new StreamReader(_underlyingStream); 
     return reader.ReadToEnd(); // we're done, but the stream is not ours to close 
    } 
} 
+2

Esta pregunta podría ayudar: http://stackoverflow.com/questions/1862261/can-you-keep-a-streamreader-from-disposing-the-underlying-stream –

+1

No relacionado con la pregunta, pero dado que el contenedor no es "propietario" de la transmisión, es posible que también desee guardar la original '_underlyingStream.Position' y restaurarlo a esa posición después de ReadToEnd() antes de regresar a la persona que llama. (Aunque, su uso puede ser tal que la persona que llama espera que la posición se vea afectada por dicha llamada, y puede guardar la posición por sí mismo si es importante). –

Respuesta

5

Si nadie cierra las transmisiones, en última instancia se llamará al finalizador, que debe llamar a deshacerse de ellas y cerrarlas en GC. Pero eso es bastante disparatado en cuanto a los recursos, ya que deja los recursos posiblemente costosos asignados hasta GC. Podría empeorar cuanto más tiempo viva su objeto, especialmente si sobrevive a las colecciones para ser promovido a gen 1 o incluso 2.

Seguro que estaría bien si pudiera presentar algo a su interlocutor que aísla esto. ¿Quizás puede almacenar en caché algo de la transmisión para que pueda cerrarlo mientras sigue sirviendo el contenido a la persona que llama?

EDIT después de su edición: Ahora que veo que su interlocutor PASE un flujo para operar, ¡mi respuesta debe ser diferente! Está muy claro que su interlocutor debería estar administrando la vida útil de la transmisión. Al principio, tuve la impresión de que su clase había creado una transmisión y esperaba que la persona que llamaba lo administrara.

0

Definitivamente no está bien. read this from msdn

El cierre llama al método Dispose pasando un valor verdadero. La descarga de la corriente no descargará su codificador subyacente a menos que llame explícitamente a Cerrar.

Trate de encapsular todo IO en una clase.

+0

No entiendo exactamente eso. ¿Por qué no enrojecer el codificador subyacente es algo malo? ¿Tiene algún enlace útil sobre lo que es? –

+1

Enrojecimiento es una cosa, pero es molesto que la eliminación de la envoltura siempre disponga la corriente, también. Por lo general, todavía desea acceder a eso desde un nivel superior. – Nyerguds

Cuestiones relacionadas