我应该为流对象调用Close()还是Dispose()?

StreamStreamReaderStreamWriter等类实现了IDisposable接口。 这意味着,我们可以在这些类的对象上调用Dispose()方法。 他们还定义了一个名为Close()public方法。 现在让我感到困惑,至于在完成对象之后应该怎么称呼? 如果我同时打电话怎么办?

我目前的代码是这样的:

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()方法。 这样对吗?

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

MSDN示例不使用using()构造,并调用Close()方法:

  • 如何:使用FTP下载文件
  • 好吗?


    快速跳转到Reflector.NET显示StreamWriter上的Close()方法是:

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

    StreamReader是:

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

    StreamReaderDispose(bool disposing)覆盖是:

    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 ( ... ) { ... }是否更具可读性。

    我个人的偏好是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。


    文件说这两种方法是等价的:

    StreamReader.Close:Close的这个实现调用Dispose方法传递一个真实值。

    StreamWriter.Close:Close的这个实现调用Dispose方法传递一个真实值。

    Stream.Close:此方法调用Dispose,指定true以释放所有资源。

    所以,这两者同样有效:

    /* Option 1 */
    using (StreamWriter writer = new StreamWriter(filename)) { 
       // do something
    } 
    
    /* Option 2 */
    StreamWriter writer = new StreamWriter(filename)
    try {
        // do something
    }
    finally {
        writer.Close();
    }
    

    就我个人而言,我会坚持第一种选择,因为它包含较少的“噪音”。

    链接地址: http://www.djcxy.com/p/54035.html

    上一篇: Should I call Close() or Dispose() for stream objects?

    下一篇: How to dispose of a System.ServiceModel.ClientBase<TChannel>?