2009-12-08 7 views
19

Nota: He leído las dos preguntas siguientes ya:Comprensión arroyos y su vida (Flush, botar, Close)

Can you explain the concept of streams?

C# using streams

estoy de codificación en C#

  1. En casi todos los ejemplos de código que usan flujos, casi siempre se llaman .Dispose(), .Flush(), .Close().
    • En el concepto de transmisión, ¿qué logra?
    • Si no dispongo de una secuencia que guardé en una variable, ¿se está filtrando mi aplicación en alguna parte?
    • ¿Por qué tengo que llamar a alguna de estas funciones? He visto ejemplos de código que no hacen esto y todavía hacer el trabajo (sin rotura aparente )

Actualmente estoy construyendo una clase en mi aplicación que contiene un método primaria (deja llaman GetStream()) que devuelve una corriente a través de myWebRequest.GetResponse().GetResponseStream()

El método principal GetStream() devuelve un objeto Stream que se puede utilizar para cualquier operación que requiere una corriente (StreamReader, Bitmap() etc.).

¿Hay alguna manera de hacer que la transmisión se elimine automáticamente después de su último uso (¿se recolectó basura?) Sin forzar a nadie que llame al .GetStream() a deshacerse de ella manualmente?

Como probablemente pueda decir, mis preguntas son vagas y generales. Mi comprensión de las transmisiones no es sólida, por lo que cualquier enlace a artículos útiles que ofrezcan una mirada más profunda a las transmisiones que una pregunta de SO puede ofrecer sería apreciado.

Respuesta

28

La eliminación de una secuencia lo cierra (y probablemente no haga mucho más). Al cerrar una secuencia, se vacía y libera todos los recursos relacionados con la secuencia, como un identificador de archivo. La descarga de una secuencia toma cualquier información almacenada que aún no se haya escrito, y la escribe de inmediato; algunas secuencias usan el almacenamiento en búfer internamente para evitar hacer una tonelada de pequeñas actualizaciones a recursos relativamente costosos como un archivo de disco o un conducto de red.

es necesario llamar a cualquiera Close o Dispose en la mayoría de los arroyos, o su código es incorrecto, porque el recurso subyacente no será liberado para otra persona a utilizar hasta que el recolector de basura viene (¿quién sabe cuánto tiempo va a tomar .) Dispose se prefiere por supuesto; se espera que elimines todas las cosas desechables en C#. Probablemente no tenga que llamar al Flush explícitamente en la mayoría de los escenarios.

En C#, es idiomática llamar Dispose por medio de un bloque de using, que es el azúcar sintáctica para un try-finally bloque que dispone en el último, por ejemplo:

using (FileStream stream = new FileStream(path)) 
{ 
    // ... 
} 

es funcionalmente idéntica a

FileStream stream; 

try 
{ 
    stream = new FileStream(path); 
    // ... 
} 
finally 
{ 
    if (stream != null) 
     stream.Dispose(); 
} 
+2

Finalmente debe ser: 'if (stream is IDisposable) ((IDisposable) stream).Dispose(); – Gonzalo

+10

Es un error del compilador utilizar 'using' en una variable que no se sabe que es IDisposable. Sin embargo, técnicamente debería ser: if (stream! = Null) stream.Dispose(); –

+0

En muchos casos, es una buena idea cerrar explícitamente una secuencia, incluso si también se llama a 'Dispose'. Cerrar una secuencia puede requerir la realización de acciones que no se puede garantizar que tengan éxito; las implementaciones de 'Close' arrojarán generalmente una excepción cuando tales problemas ocurran, mientras que algunas implementaciones' Dispose' pueden sofocar tales excepciones (tragarse tales excepciones es malo, pero permitirles propagarse fuera de 'Dispose' a menudo golpeará una excepción previa, que también es malo; las implementaciones difieren en cuanto a qué mal se considera menor). – supercat