c# using + XmlWriter.Create =“无法访问关闭的流". [英] c# using + XmlWriter.Create = "Cannot access a closed Stream."
问题描述
为什么会这样:
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)
but this does not work ("Cannot access a closed Stream."):
Only difference is var dummy = XmlWriter.Create(ms)
instead of 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:
这也不起作用(同样的错误):
Also this does not work (same 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();
}
}
}
堆栈跟踪:
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
w/o using
):
but this works (only difference is 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();
}
}
推荐答案
你能给我们完整的异常堆栈跟踪吗?我的第一个猜测是 XmlWriter
仍然尝试访问 XmlWriter
的 Dispose()
方法内的流.
Can you give us the complete stack trace of the exception? My first guess is that the XmlWriter
still tries to access the stream within the Dispose()
method of the XmlWriter
.
在您的第二个和第四个代码示例中,您将 StreamReader
放在 using 块中.这会导致在此块的末尾调用 StreamReader
的 Dispose()
方法.此方法关闭读取器和底层流.此后,XmlWriter
的 Dispose()
方法无法再访问流.
In your second and fourth code example you place the StreamReader
in a using-block. This causes the invocation of the Dispose()
method of the StreamReader
at the end of this block. This method closes both the reader and the underlying stream. After this, the Dispose()
method of the XmlWriter
can't access the stream anymore.
更新:基于stackstrace,我似乎是对的.Dispose()
方法调用 Close()
,后者又要刷新已经关闭的流.这看起来像一个错误,因为应该没有任何东西可以刷新.
Update:
Based on the stackstrace it seems I was right. The Dispose()
method invokes Close()
, which in turn wants to flush an already closed stream. This looks like a bug since there should be nothing left to flush.
您已经给出了解决方案:在 XmlWriter 处理之前不要关闭内存流.
You already gave the solution: don't close the memorystream before the XmlWriter disposes.
(我假设您知道 using 块隐式处理使用的对象,而处理 StreamReader
或 StreamWriter
隐式处理(并关闭)底层流.)
(I assume you know that a using-block implicitly disposes the used object, and that disposing a StreamReader
or StreamWriter
implicitly disposes (and closes) the underlying stream.)
这篇关于c# using + XmlWriter.Create =“无法访问关闭的流".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!