2012-03-23 19 views
6

Así que estoy usando el filestream dentro xmlreaderPor qué filestream no cierra por xmlreader

using (XmlReader reader = XmlReader.Create(new FileStream(archivePath, FileMode.Open), readerSettings)) 
{ 
    reader.close() 
} 

Sin embargo, la alimentación de archivo en el xmlreader todavía en el estado de bloqueo después de que el uso de alcance, extraño, Me vestuario del xmlreader va para cerrar la cadena de archivos para mí, ¿no es así?

Gracias por la ayuda.

Respuesta

7

¿Has probado esto?

using(var stream = new FileStream(archivePath, FileMode.Open)) 
using(var reader = XmlReader.Create(stream, readerSettings)) 
{ 

} 

no pude encontrar nada en la documentación que establece explícitamente que el XmlReader llamarían disponer en la secuencia subyacente cuando se disponía. Además, siempre lo uso como se muestra arriba y nunca he encontrado un problema.

Examinando el reflector También encuentro ningún caso en el que se llame al Dispose() en la secuencia al crear un XmlTextReaderImpl. El XmlTextReaderImpl no implementa Dispose() y su método Close() se parece a esto:

internal void Close(bool closeInput) 
{ 
    if (this.parsingFunction != ParsingFunction.ReaderClosed) 
    { 
     while (this.InEntity) 
     { 
      this.PopParsingState(); 
     } 
     this.ps.Close(closeInput); 
     this.curNode = NodeData.None; 
     this.parsingFunction = ParsingFunction.ReaderClosed; 
     this.reportedEncoding = null; 
     this.reportedBaseUri = string.Empty; 
     this.readState = ReadState.Closed; 
     this.fullAttrCleanup = false; 
     this.ResetAttributes(); 
    } 
} 
+1

para ser honesto, no. Pensé que XmlReader es como StreamReader, cerrará la transmisión interna una vez hecho. usar dos instrucciones de uso es un poco torpe. –

+1

anecdótico, pero la mayoría de los ejemplos que veo utilizan los dos 'using'. –

+1

@TOMMYWANG: Bueno, puedes pensarlo, pero no puedo encontrar ningún lugar en el código (usando el reflector) donde 'XmlTextReaderImpl' (que es lo que' XmlReader.Create() 'realmente devuelve) elimina la transmisión. Si cierra la transmisión, se producirán problemas al usar una secuencia para múltiples lectores (¿qué pasa si quiero mantener la transmisión activa? ¿Por qué el lector debe decidir que no puedo?), Por lo que se necesita un enfoque seguro para hacer nada. No estoy de acuerdo con que sea "torpe", pero "torpe" es mejor que "roto". –

1

Usted tendría que hacer un seguimiento de la FileStream y la XmlReader. Es potencialmente peligroso para el XmlReader cerrar la transmisión subyacente. En el caso en que el FileStream es utilizado por varios lectores: si uno de estos lectores cerrara la secuencia, esto provocaría que los otros lectores fallaran inesperadamente.

Es un poco molesto ya que algunos lectores y escritores de flujo cerrarán el flujo subyacente, mientras que otros no lo harán. Como práctica recomendada siempre cierro y desecho las transmisiones que abro manualmente. Esto también ayuda a mitigar algunas 'trampas' con ciertas transmisiones.
p. You need to dispose a GZipStream before calling .ToArray()

9

Debería poder controlar esto a través de XmlReaderSettings.CloseInput.

readerSettings.CloseInput = true; 
using (XmlReader reader = XmlReader.Create(new FileStream(archivePath, FileMode.Open), readerSettings)) 
{ 
    // do work with the reader 
} 

O, de manera más concisa si no se preocupan por otras configuraciones del lector:

using (XmlReader reader = XmlReader.Create(new FileStream(archivePath, FileMode.Open), new XmlReaderSettings() { CloseInput = true })) 
{ 
    // do work with the reader 
} 
+1

Buena respuesta, esto evita que FxCop se queje de las múltiples disposiciones si establecer CloseInput = false, que me molestaba. – briantyler

+0

¿No es redundante la sentencia reader.close() aquí porque al salir de la instrucción using se invocará Dispose() y se llamará Close()? – Kent

0

unos años tarde, pero tal vez esto puede ayudar a alguien ...

me trataron método de Eric ya que parecía una buena solución, pero seguí recibiendo la advertencia CA2202 cuando ejecuté el análisis de código VS en él.

En la parte inferior de CA2202, Microsoft recomienda utilizar los siguientes: (i. Ligeramente modificado el que para "XmlReader")

Stream stream = null; 
try 
{ 
    stream = new FileStream("file.txt", FileMode.Open); 
    using (XmlReader reader = new XmlReader (stream)) 
    { 
     stream = null; 
     // Use the reader object... 
    } 
} 
finally 
{ 
    if(stream != null) 
     stream.Dispose(); 
} 

en lugar de ...

using (Stream stream = new FileStream("file.txt", FileMode.Open)) 
{ 
    using (XmlReader reader = new XmlReader (stream)) 
    { 
     // Use the reader object... 
    } 
} 

Es mucho más largo, pero al menos no arroja ninguna advertencia.

Cuestiones relacionadas