MemoryStream.Close()或MemoryStream.Dispose()

ash*_*rya 60 .net c# garbage-collection

我打电话给哪一个?

是否有必要同时打电话?

如果我已经打过其中一个,那么另一个会抛出异常吗?

cdh*_*wie 108

Close()而且Dispose(),当被召唤时MemoryStream,只做两件事:

  • 标记处置的对象,以便将来意外使用该对象将引发异常.
  • 可能是1个版本对托管对象的引用,这可以使GC的工作更容易,具体取决于GC的实现.(在今天的GC算法上,它没有什么真正的区别,所以这是学术讨论的一个点,并且没有重大的现实影响.)

MemoryStream没有任何非托管资源可供处置,因此您在技术上不必处置它.不处理a的效果MemoryStream与删除对a的引用大致相同byte[]- GC将以相同的方式清除它们.

我打电话给哪一个?是否有必要同时打电话?

Dispose()流的方法代表直接向Close()2,这样既做同样的事情.

如果我已经打过其中一个,那么另一个会抛出异常吗?

具体说明在任何对象上多次调用是安全的文档IDisposable.Dispose()3.(如果对于特定类不是这样,那么该类以违反其合同的方式实现接口,这将是一个错误.)Dispose()IDisposable

所有这一切:无论你是否弃置,它确实没有太大的区别MemoryStream.它唯一的真正原因Close/ Dispose方法,是因为它继承Stream,这需要这些方法作为合同的一部分,以支持流有非托管资源(例如文件或套接字描述符).


1 Mono的实现不会发布byte[]参考.我不知道微软的实现是否如此.

2 "此方法调用Close,然后调用Stream.Dispose(Boolean)."

3 "如果一个对象的Dispose方法被多次调用,该对象必须忽略第一个之后的所有调用."

  • 根据[.NET参考资料来源](http://referencesource.microsoft.com/),参考你的脚注`1``.Dispose()`也不释放内部`byte []`.它设置为`null`的唯一资源是`_lastReadTask`,它仅用于方法`Task <int> ReadAsync(byte [],int,int,CancellationToken)`.除了将一个变量设置为null之外,它还将`_isOpen`,`_writable`和`_expandable`设置为`false`. (3认同)

Tal*_*ner 7

使用using块,以便在实现IDisposable接口时处置对象


Kev*_*vin 7

您可以使用此using块.Dispose当它超出其范围时,它将自动调用.

例:

using (MemoryStream ms = new MemoryStream())
{
    // Do something with ms..
}
// ms is disposed here
Run Code Online (Sandbox Code Playgroud)

希望这有帮助.


Qry*_*taL 6

我叫哪一个?

任何一位。

有必要同时调用吗?

不,任何一个都足够了。

如果我已经调用了其中一个,另一个会抛出异常吗?

不,一次性模式声明对 Dispose 的后续调用不会造成负面影响。


vc *_* 74 5

如您所见,以下代码是来自反射器的 Stream.Dispose,如果您处理,则不需要关闭(使用 using 时是隐式的)

public void Dispose()
{
    this.Close();
}
Run Code Online (Sandbox Code Playgroud)


Edw*_*rey 5

以上都不是。您无需致电CloseDispose

MemoryStream不包含任何非托管资源,因此唯一需要回收的资源是内存。MemoryStream当您的代码不再引用时,在垃圾回收期间将与对象的其余部分一起回收内存MemoryStream

如果您有对的长期引用,则MemoryStream可以将该引用设置为null以允许MemoryStream对进行垃圾回收。CloseDispose释放蒸汽缓冲器和MemoryStream适当的物体。

由于既Stream没有MemoryStream终结器也没有终结器,因此无需调用CloseDispose导致GC.SuppressFinalize被调用来优化垃圾回收。没有终结器可以抑制。

MemoryStream的文档是这样写的:

此类型实现IDisposable接口,但实际上没有任何资源可配置。这意味着不需要直接调用Dispose()或使用诸如using(在C#中的)或Using(在Visual Basic中的)语言结构来处置它。