对于流对象,我应该调用CLOSE()还是Dispose()?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (17)

类如StreamStreamReaderStreamWriter等工具IDisposable界面。这意味着,我们可以调用Dispose()这些类的对象的方法。他们还定义了一个public叫做的方法Close()。现在让我感到困惑,至于在完成对象之后应该怎么称呼?如果我同时调用怎么办?

我目前的代码是这样的:

using (Stream responseStream = response.GetResponseStream())
{
   using (StreamReader reader = new StreamReader(responseStream))
   {
      using (StreamWriter writer = new StreamWriter(filename))
      {
         int chunkSize = 1024;
         while (!reader.EndOfStream)
         {
            char[] buffer = new char[chunkSize];
            int count = reader.Read(buffer, 0, chunkSize);
            if (count != 0)
            {
               writer.Write(buffer, 0, count);
            }
         }
         writer.Close();
      }
      reader.Close();
   }
}

正如你所看到的,我已经写了using()构造,它会自动调用Dispose()每个对象的方法。但我也叫Close()方法。这样对吗?

请在使用流对象时向我建议最佳做法。

提问于
用户回答回答于

快速跳转到Reflector.NET表明该Close()方法StreamWriter是:

public override void Close()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

并且StreamReader是:

public override void Close()
{
    this.Dispose(true);
}

Dispose(bool disposing)超控StreamReader是:

protected override void Dispose(bool disposing)
{
    try
    {
        if ((this.Closable && disposing) && (this.stream != null))
        {
            this.stream.Close();
        }
    }
    finally
    {
        if (this.Closable && (this.stream != null))
        {
            this.stream = null;
            /* deleted for brevity */
            base.Dispose(disposing);
        }
    }
}

StreamWriter方法类似。

因此,阅读代码很明显,你可以随时随地以任何顺序调用Close()Dispose()流。它不会以任何方式改变行为。

所以这取决于它是否更易于使用Dispose()Close()和/或using ( ... ) { ... }

但是,虽然这有助于正确性,但确实降低了可读性。在C#中,我们已经有了大量的大括号,因此我们如何知道哪一个实际执行了关闭流?

所以我认为最好这样做:

using (var stream = ...)
{
    /* code */

    stream.Close();
}

它不会影响代码的行为,但确实有助于可读性。

用户回答回答于

不,你不应该手动调用这些方法。在块的结尾处using,会自动调用Dispose方法,这将自动调用释放非托管资源(至少对于标准的.NET BCL类,如流,读者/写者等)。所以你也可以这样写你的代码:

using (Stream responseStream = response.GetResponseStream())
    using (StreamReader reader = new StreamReader(responseStream))
        using (StreamWriter writer = new StreamWriter(filename))
        {
            int chunkSize = 1024;
            while (!reader.EndOfStream)
            {
                 char[] buffer = new char[chunkSize];
                 int count = reader.Read(buffer, 0, chunkSize);
                 if (count != 0)
                 {
                     writer.Write(buffer, 0, count);
                 }
            }
         }

Close方法调用Dispose。

扫码关注云+社区