c# using + XmlWriter.Create =“无法访问关闭的流". [英] c# using + XmlWriter.Create = "Cannot access a closed Stream."

查看:39
本文介绍了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)

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 仍然尝试访问 XmlWriterDispose() 方法内的流.

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 块中.这会导致在此块的末尾调用 StreamReaderDispose() 方法.此方法关闭读取器和底层流.此后,XmlWriterDispose() 方法无法再访问流.

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 块隐式处理使用的对象,而处理 StreamReaderStreamWriter 隐式处理(并关闭)底层流.)

(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆