2011-03-30 42 views
7

爲什麼這個工程:( 「無法訪問已關閉的流」)c#using + XmlWriter.Create =「無法訪問封閉的流。」

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(); 
     } 
    } 
} 

但這不起作用: 唯一的區別是var dummy = XmlWriter.Create(ms)代替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(); 
     } 
    } 
} 

堆棧跟蹤:

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: 

而且這不工作(同樣的錯誤):

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(); 
     } 
    } 
} 

堆棧跟蹤:

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: 

但這個工程(唯一的區別是StreamReader瓦特/ 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

沒有在Silverlight 4上重現,我沒想到會有一個。 – 2011-03-30 01:22:47

+0

這是Silverlight 3. – Pol 2011-03-30 01:24:38

+0

你找到了一個很好的升級理由。 – 2011-03-30 01:28:06

回答

4

,你能不能給我們異常的完整堆棧跟蹤?我的第一個猜測是XmlWriter仍試圖將XmlWriterDispose()方法中訪問流。

在你的第二個和第四個代碼示例您將StreamReader在使用塊。這導致StreamReaderDispose()方法的調用在該塊的結束。此方法關閉閱讀器和基礎流。在此之後,XmlWriterDispose()方法無法再訪問該流。

更新: 基於stackstrace看來我是對的。該Dispose()方法調用Close(),這反過來又要刷新的已關閉流。這看起來像一個錯誤,因爲應該沒有什麼可以刷新。

你已經給瞭解決方案:XmlWriter的處置前不關閉的MemoryStream。

(我假設你知道,使用塊隱含部署的使用對象,並設置一StreamReaderStreamWriter隱含部署(並關閉)底層流。)

+0

我添加了堆棧跟蹤。 – Pol 2011-03-30 02:14:17

13

剛剛擺脫的MemoryStream塊寫上一個與寫入它的水平。

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

完美的,有同樣的問題試圖獲得一個XmlSchema字符串。一旦我像這裏所示的那樣移動那個區塊,一切都很好。 – DubMan 2017-11-27 17:28:01

相關問題