Stream.Dispose是否总是调用Stream.Close(和Stream.Flush)

如果我有以下情况:

StreamWriter MySW = null; try { Stream MyStream = new FileStream("asdf.txt"); MySW = new StreamWriter(MyStream); MySW.Write("blah"); } finally { if (MySW != null) { MySW.Flush(); MySW.Close(); MySW.Dispose(); } } 

我可以只是调用MySW.Dispose()并跳过closures即使它提供? 有什么Stream implimentations不能按预期工作(像CryptoStream)?

如果不是,那么下面就是不好的代码:

 using (StreamWriter MySW = new StreamWriter(MyStream)) { MySW.Write("Blah"); } 

我可以只是调用MySW.Dispose()并跳过closures即使它提供?

是的,就是这样。

是否有任何Stream实现不能按预期工作(如CryptoStream)?

假设一个对象实现了IDisposable ,它可以很好地处理它自己。

如果没有,那么这将是一个错误。

如果不是,那么下面就是不好的代码:

不,该代码是处理实现IDisposable对象的推荐方式。

在接受和处置的接受答案中有更多优秀的信息- 要调用哪一个?

我使用reflection器,发现System.IO.Stream.Dispose看起来像这样:

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

正如丹尼尔·布鲁克纳(Daniel Bruckner)提到的,处置和closures实际上是一回事。

但是Stream在处理/closures时不调用Flush()。 FileStream(和我认为任何其他与caching机制的stream)不处理时调用Flush()。

如果您正在扩展Stream或MemoryStream等,则在需要处理/closures时,需要实现对Flush()的调用。

StreamWriter.Dispose()和Stream.Dispose()都释放对象所拥有的所有资源。 他们都closures了基础stream。

Stream.Dispose()的源代码(请注意,这是实现细节,所以不要依赖它):

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

StreamWriter.Dispose()(与Stream.Dispose()相同):

 protected override void Dispose(bool disposing) { try { // Not relevant things } finally { if (this.Closable && (this.stream != null)) { try { if (disposing) { this.stream.Close(); } } finally { // Not relevant things } } } } 

不过,我通常在处理它们之前暗中closuresstream/ streamwriters – 我认为它看起来更干净。

所有标准stream(FileStream,CryptoStream)将在closures/处理时尝试刷新。 我想你可以依靠任何Microsoftstream实现这个。

因此,如果刷新失败,Close / Dispose可能会抛出exception。

实际上,IIRC在FileStream的.NET 1.0实现中存在一个错误,那就是如果flush引发exception,将无法释放文件句柄。 这是通过添加一个try / finally块到Dispose(boolean)方法在.NET 1.1中修复的。

对于需要手动closures的对象,应尽一切努力在使用块中创build对象。

 //Cannot access 'stream' using (FileStream stream = File.Open ("c:\\test.bin")) { //Do work on 'stream' } // 'stream' is closed and disposed of even if there is an exception escaping this block // Cannot access 'stream' 

通过这种方式,永远不会在using子句的上下文中错误地访问'stream',并且文件总是被closures。

我查看了Stream类的.net源文件,它具有以下内容,表明可以。

  // Stream used to require that all cleanup logic went into Close(), // which was thought up before we invented IDisposable. However, we // need to follow the IDisposable pattern so that users can write // sensible subclasses without needing to inspect all their base // classes, and without worrying about version brittleness, from a // base class switching to the Dispose pattern. We're moving // Stream to the Dispose(bool) pattern - that's where all subclasses // should put their cleanup starting in V2. public virtual void Close() { Dispose(true); GC.SuppressFinalize(this); } public void Dispose() { Close(); } 

Stream.Close是通过调用Stream.Close来实现的,反之亦然 – 所以这些方法是等价的。 Stream.Close只是因为closuresstream听起来比Stream.Closestream更自然。

此外,您应该尽量避免显式调用此方法,而是使用using语句来获得正确的免费exception处理。