2011-05-31 76 views

回答

5

只是为了好玩,我打开反编译器,看看Dispose在StreamWriter上做了些什么(或许底层流是需要处理的唯一资源)。这里是出来了:

protected override void Dispose(bool disposing) 
{ 
    try 
    { 
     if (this.stream != null) 
     { 
      if (disposing || (this.Closable || this.stream as __ConsoleStream)) 
      { 
       this.Flush(true, true); 
       if (this.mdaHelper != null) 
       { 
        GC.SuppressFinalize(this.mdaHelper); 
       } 
      } 
     } 
    } 
    finally 
    { 
     if (this.Closable) 
     { 
      if (this.stream != null) 
      { 
       if (disposing) 
       { 
        this.stream.Close(); 
       } 
       this.stream = null; 
       this.byteBuffer = null; 
       this.charBuffer = null; 
       this.encoding = null; 
       this.encoder = null; 
       this.charLen = 0; 
       base.Dispose(disposing); 
      } 
     } 
    } 
} 

有点罗嗦,但我认为这是什么告诉我们的是,配置流采用由StreamWriter的唯一使用的一次性资源的照顾。 byteBuffercharBuffer字段是数组,encodingencoder不是一次性的,并且基础Dispose是虚拟的,所以如果没有清理,Stream是唯一会导致问题的东西。

我想,这也清楚地表明,如果你想记录的数据流中的内容,并使其保持可用状态之后,那么你最挑衅做要处置您的StreamWriter的,因为这将处理流(Close calls Dispose(true))。您还希望确保重置流的位置,因为您无疑会通过阅读内容来更改它的位置。当然,这也意味着你可能想检查Stream上的CanSeek属性,并确保一旦你阅读了内容,你将能够返回到之前的位置。

+0

我很担心泄漏,设计提供了你准确的说法 – 2011-06-01 11:17:25

0

作为一种最佳实践,您应该在不再需要时立即关闭它。但是,垃圾收集应该在离开本地函数作用域时将其标记为清除。

+0

你错过了关于清理流的调用者的观点。 – 2011-05-31 22:15:30

+0

啊,是的,我确定。我没有明白。很抱歉对于这个误会。 – BAKeele 2011-06-01 16:15:49

-2

这不是我的强项,但是你应该把StreamWriter放到Using()块中,处置streamwriter不应该处理流。如果它确实放弃了流,那么您希望返回Streamwriter引用,以便可以进一步清理。

编辑:微软的偶然编码。 StreamWriter不会处理流,因为您可以在@ckramer的答案中直接看到它,它的流是Close。挖掘关闭方法http://msdn.microsoft.com/en-us/library/system.io.stream.close.aspx

此方法调用Dispose,指定true以释放所有资源。您不必专门调用Close方法。相反,请确保每个Stream对象都妥善处置。

很高兴看到微软直接忽略了自己的言论。它会变得更好。

给实现

在派生类,不重写Close方法,相反,把所有的流清理逻辑在Dispose方法。

这绝对没有意义。因此,他们不仅忽略了他们的第一条语句,他们创建了一个违反开放 - 闭合原则的类,从而使您能够以可能导致意外情况的方式修改该类。对于这样的陈述,Close应该绝对不是虚拟的,或者他们应该固定任何推理进入这个考虑的。

+0

盲人DV?争辩你的很多。 – 2011-06-01 15:14:43

+0

只是不正确。 – 2013-03-21 14:19:55

0

如果垃圾收集器没有被引用,它肯定会被垃圾收集器处置,因为它实现了IDisposable。
让垃圾收集器处置它的问题是它处置的时刻不确定,并取决于几个条件。
所以理论上它不会导致内存泄漏,但它会让您的应用程序在更多时间使用更多的资源,这可能会非常低效。

+0

调用者关闭流。作者没有(其他)资源。 – 2011-05-31 18:55:14