使用“using”语法时流关闭错误

时间:2011-06-20 07:21:08

标签: c# .net exception stream

我将在下面留下我原来的问题。我的问题是为什么以下行产生异常

(你可以看到它在http://www.ideone.com/rfQLE运行)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace CSQuick
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var ff = new MemoryStream())
            using (var f = new StreamWriter(ff))
            {
                f.WriteLine("Hi");
                using (TextReader ts = new StreamReader(ff))
                {
                }
            }
        }
    }
}

来自ideone网站的异常(可能使用mono?我正在运行MSVS 2010 C#导致异常)

Unhandled Exception: System.ObjectDisposedException: The object was used after being disposed.
  at System.IO.MemoryStream.CheckIfClosedThrowDisposed () [0x00000] in <filename unknown>:0 
  at System.IO.MemoryStream.Write (System.Byte[] buffer, Int32 offset, Int32 count) [0x00000] in <filename unknown>:0 
  at System.IO.StreamWriter.FlushBytes () [0x00000] in <filename unknown>:0 
  at System.IO.StreamWriter.Flush () [0x00000] in <filename unknown>:0 
  at System.IO.StreamWriter.Dispose (Boolean disposing) [0x00000] in <filename unknown>:0 

为什么我收到msg“无法访问已关闭的流”的异常。 ?我想做的是使用一个streamwriter来编写文本并将最终结果存储在temp中。下面应该这样做,但我不明白我的流是如何或为什么关闭?

using (var ff = new MemoryStream())
using (var f = new StreamWriter(ff))
{
    foreach (var t in blah)
    {
        blahblah(t, f);
    }
    ff.Flush()
    using (TextReader ts = new StreamReader(ff))
    {
        temp = ts.ReadToEnd();
        do_a_check(fn, temp);
    }
}//Cannot access a closed Stream.

4 个答案:

答案 0 :(得分:5)

您没有提供太多信息,但我认为错误是因为当StreamWriter using子句完成并且StreamWriter关闭时,底层流也会关闭。在这种情况下,当您尝试在using语句之后访问流时您将收到错误“无法访问已关闭的流”

using (var ff = new MemoryStream())
{
using (var f = new StreamWriter(ff))
{
//Some Code
}
//Stream ff is closed, because the StreamWriter has been closed while exiting the inner using statement
}

答案 1 :(得分:4)

当您处理TextReader时,其中的资源也会被释放(MemoryStream)。因此,当StreamWriter被释放时,它会刷新,从而写入已处理的MemoryStream。

您的小型repro代码可以更改为flush:

    static void Main(string[] args)
    {
        using (var ff = new MemoryStream())
        using (var f = new StreamWriter(ff))
        {
            f.WriteLine("Hi");
            f.Flush();
            using (TextReader ts = new StreamReader(ff))
            {
            }
        }
    }

或者您可以设置AutoFlush,这将导致每次写入刷新流,如果您在处置后没有写入写行,则不会出现此异常:

static void Main(string[] args)
{
    using (var ff = new MemoryStream())
    using (var f = new StreamWriter(ff))
    {
        f.AutoFlush = true;
        f.WriteLine("Hi");
        using (TextReader ts = new StreamReader(ff))
        {
        }
    }
}

答案 2 :(得分:0)

您应该显示更有用的堆栈跟踪。

到目前为止,我认为在使用块中问题是StreamReader,处理器关闭了读取器和底层流

答案 3 :(得分:-2)

在你的代码中

using (var ff = new MemoryStream())

应自动配置MemoryStream,添加一些{}以扩展范围。或者删除使用代码,然后在代码周围添加一个try catch。