本文介绍了即使在MemoryStream.Close()之后,对MemoryStream.GetBuffer()的调用也会成功.为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一些开源代码中发现了以下结构:

var mstream = new MemoryStream();
// ... write some data to mstream
mstream.Close();
byte[] b = mstream.GetBuffer();

我认为此代码将具有意外"行为,并且可能引发异常,因为根据 MSDN文档.

但是,据我所知,对GetBuffer()的调用始终会成功并返回有效结果,即使我Thread.Sleep 20秒钟或通过GC.Collect()强制执行垃圾回收. /p>

即使在Close/Dispose之后,对GetBuffer()的调用也应该成功吗?在那种情况下,为什么在MemoryStream处理中不释放基础缓冲区?

解决方案
  1. 不需要.缓冲区是托管内存,因此正常的垃圾回收将对其进行处理,而无需将其包含在处置中.
  2. 即使关闭了流,也能够获取内存流的字节是很有用的(在将蒸汽传递给向流中写入内容然后关闭所述流的方法之后,这可能会自动发生) .为此,该对象需要保留在缓冲区中,并记录已写入缓冲区的数量.

在考虑第二点时,实际上在许多情况下调用ToArray()更为有意义(如上所述,这要求GetBuffer()返回的内存存储仍然有效) /strong>已关闭流,因为关闭流可确保任何进一步写入流的尝试均将失败.因此,如果您有一个过早获取数组的错误,它将引发异常,而不仅仅是给您不正确的数据. (显然,如果您明确希望在流操作的途中获得当前数组,那是另一回事).它还保证所有流都被完全刷新,而不是将其部分数据存储在临时缓冲区中(由于MemoryStream本质上是缓冲区,因此未缓冲MemoryStream,但是您可能一直在使用它与链式流或具有自己单独缓冲区的编写器一起使用.

I have found the following construct in some open-source code:

var mstream = new MemoryStream();
// ... write some data to mstream
mstream.Close();
byte[] b = mstream.GetBuffer();

I thought this code would have "unexpected" behavior and maybe throw an exception, since the call to Close should effectively be a call to Dispose according to the MSDN documentation.

However, as far as I have been able to tell from experimenting, the call to GetBuffer() always succeeds and returns a valid result, even if I Thread.Sleep for 20 seconds or enforce garbage collection via GC.Collect().

Should the call to GetBuffer() succeed even after Close/Dispose? In that case, why is not the underlying buffer released in the MemoryStream disposal?

解决方案
  1. It doesn't need to. The buffer is managed memory, so normal garbage collection will deal with it, without needing to be included in the disposal.
  2. It's useful to be able to get the bytes of the memory stream, even after the stream has been closed (which may have happened automatically after the steam was passed to a method that writes something to a stream and then closes said stream). And for that to work, the object needs to hold onto the buffer along with a record of how much had been written to it.

In considering the second point, it actually makes more sense in a lot of cases to call ToArray() (which as said, requires the in-memory store that GetBuffer() returns to still be alive) after you've closed the stream, because having closed the stream guarantees that any further attempt to write to the stream will fail. Hence if you have a bug where you obtain the array too early, it will throw an exception rather than just give you incorrect data. (Obviously if you explicitly want to get the current array part-way through the stream operations, that's another matter). It also guarantees that all streams are fully flushed rather than having part of their data in a temporary buffer (MemoryStream isn't buffered because MemoryStream essentially is a buffer, but you may have been using it with chained streams or writers that had their own separate buffer).

这篇关于即使在MemoryStream.Close()之后,对MemoryStream.GetBuffer()的调用也会成功.为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 04:47