2011-03-30 13 views
7

Por qué esto funciona: ("No se puede acceder a una corriente cerrada")C# using + XmlWriter.Create = "No se puede acceder a una secuencia cerrada".

using (var ms = new MemoryStream()) 
{ 
    using (var dummy = new StreamWriter(ms)) 
    { 
     var sw = new StreamWriter(ms); 
     sw.WriteLine("Hello World"); 
     sw.Flush(); 
     using (StreamReader rdr = new StreamReader(ms)) 
     { 
      ms.Position = 0; 
      textBoxExc.Text = rdr.ReadToEnd(); 
     } 
    } 
} 

pero esto no funciona: La única diferencia es var dummy = XmlWriter.Create(ms) en lugar de var dummy = new StreamWriter(ms)

using (var ms = new MemoryStream()) 
{ 
    using (var dummy = XmlWriter.Create(ms)) 
    { 
     var sw = new StreamWriter(ms); 
     sw.WriteLine("Hello World"); 
     sw.Flush(); 
     using (StreamReader rdr = new StreamReader(ms)) 
     { 
      ms.Position = 0; 
      textBoxExc.Text = rdr.ReadToEnd(); 
     } 
    } 
} 

Seguimiento de la pila:

System.ObjectDisposedException was unhandled by user code 
    Message=Cannot access a closed Stream. 
    ObjectName="" 
    StackTrace: 
     w System.IO.__Error.StreamIsClosed() 
     w System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) 
     w System.Xml.XmlUtf8RawTextWriter.FlushBuffer() 
     w System.Xml.XmlUtf8RawTextWriter.Flush() 
     w System.Xml.XmlWellFormedWriter.Close() 
     w System.Xml.XmlWriter.Dispose(Boolean disposing) 
     w System.Xml.XmlWriter.Dispose() 
     w SerializeTest.MainPage.buttonExc_Click(Object sender, RoutedEventArgs e) 
     w System.Windows.Controls.Primitives.ButtonBase.OnClick() 
     w System.Windows.Controls.Button.OnClick() 
     w System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e) 
     w System.Windows.Controls.Control.OnMouseLeftButtonUp(Control ctrl, EventArgs e) 
     w MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName) 
    InnerException: 

También esto no funciona (mismo error):

using (var ms = new MemoryStream()) 
{ 
    using (var writer = XmlWriter.Create(ms)) 
    { 
     var serializer = new DataContractSerializer(typeof(T)); 
     serializer.WriteObject(writer, objectToSave); 
     writer.Flush(); 
     ms.Position = 0; 
     using (StreamReader rdr = new StreamReader(ms)) 
     { 
      return rdr.ReadToEnd(); 
     } 
    } 
} 

Seguimiento de la pila:

System.ObjectDisposedException was unhandled by user code 
    Message=Cannot access a closed Stream. 
    ObjectName="" 
    StackTrace: 
     w System.IO.__Error.StreamIsClosed() 
     w System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) 
     w System.Xml.XmlUtf8RawTextWriter.FlushBuffer() 
     w System.Xml.XmlUtf8RawTextWriter.Flush() 
     w System.Xml.XmlWellFormedWriter.Close() 
     w System.Xml.XmlWriter.Dispose(Boolean disposing) 
     w System.Xml.XmlWriter.Dispose() 
     w SerializeTest.SerializeToStringTest[T](T objectToSave) 
     w SerializeTest.MainPage.button2A_Click(Object sender, RoutedEventArgs e) 
     w System.Windows.Controls.Primitives.ButtonBase.OnClick() 
     w System.Windows.Controls.Button.OnClick() 
     w System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e) 
     w System.Windows.Controls.Control.OnMouseLeftButtonUp(Control ctrl, EventArgs e) 
     w MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName) 
    InnerException: 

pero esto funciona (única diferencia es StreamReader w/o using):

using (var ms = new MemoryStream()) 
{ 
    using (var writer = XmlWriter.Create(ms)) 
    { 
     var serializer = new DataContractSerializer(typeof(T)); 
     serializer.WriteObject(writer, objectToSave); 
     writer.Flush(); 
     ms.Position = 0; 
     StreamReader rdr = new StreamReader(ms); 
     return rdr.ReadToEnd(); 
    } 
} 
+1

No repro en Silverlight 4, no esperaba uno. –

+0

Es Silverlight 3. – Pol

+0

Has encontrado una buena razón para actualizar. –

Respuesta

4

Puede darnos el seguimiento de la pila completa de la excepción? Mi primera suposición es que el XmlWriter todavía intenta acceder a la secuencia dentro del método Dispose() del XmlWriter.

En su segundo y cuarto ejemplo de código coloca el StreamReader en un bloque de uso. Esto provoca la invocación del método Dispose() del StreamReader al final de este bloque. Este método cierra tanto el lector como la transmisión subyacente. Después de esto, el método Dispose() del XmlWriter ya no puede acceder a la transmisión.

Actualización: Basado en la pila de datos, parece que tenía razón. El método Dispose() invoca Close(), que a su vez quiere eliminar una secuencia ya cerrada. Esto parece un error ya que no debería haber nada para descargar.

Usted ya dio la solución: no cierre el flujo de memoria antes de que el XmlWriter disponga.

(supongo que usted sabe que un bloque utilizando dispone implícitamente el objeto utilizado, y que la disposición de un StreamReader o StreamWriter dispone implícitamente (y cierra) la corriente subyacente.)

+0

Agregué el seguimiento de la pila. – Pol

13

basta con mover la lectura del bloque MemoryStream en una nivelar con escribir en él.

using (var ms = new MemoryStream()) 
{ 
    using (var writer = XmlWriter.Create(ms)) 
    { 
     var serializer = new DataContractSerializer(typeof(T)); 
     serializer.WriteObject(writer, objectToSave); 
     writer.Flush(); 
     ms.Position = 0;   
    } 
    using (StreamReader rdr = new StreamReader(ms)) 
    { 
     return rdr.ReadToEnd(); 
    } 
} 
+0

Perfecto, tuvo el mismo problema al intentar obtener un XmlSchema en una cadena. Una vez que moví ese bloque como se muestra aquí, todo estuvo bien. – DubMan

Cuestiones relacionadas