CopyToAsync 与 ReadAsStreamAsync 的巨大请求负载
CopyToAsync vs ReadAsStreamAsync for huge request payload
我必须为巨大的负载计算散列,所以我使用流不加载内存中的所有请求内容。问题是这段代码有什么区别:
using (var md5 = MD5.Create())
using (var stream = await authenticatableRequest.request.Content.ReadAsStreamAsync())
{
return md5.ComputeHash(stream);
}
还有那个:
using (var md5 = MD5.Create())
using (var stream = new MemoryStream())
{
await authenticatableRequest.request.Content.CopyToAsync(stream);
stream.Position = 0;
return md5.ComputeHash(stream);
}
我希望在内部有相同的行为,但也许我遗漏了什么。
I expect the same behavior internally,
为什么?我的意思是,在一种情况下,您必须将所有内容加载到内存中(因为猜猜看,您定义了一个内存流)。其他情况不一定。
第一个版本看起来不错,让散列器处理流读取。它就是为此而设计的。
ComputeHash(stream)
将在 while 循环中读取块并重复调用 TransformBlock()。
但是第二段代码会将所有内容加载到内存中,所以不要那样做:
using (var stream = new MemoryStream())
{
await authenticatableRequest.request.Content.CopyToAsync(stream);
第二个片段不仅会将所有内容加载到内存中,而且会比 HttpContent.ReadAsByteArrayAsync()
.
使用 更多 内存
MemoryStream 是一个 Stream API 在 byte[]
buffer whose initial size is zero. As data gets written into it, the buffer has to be reallocated 上进入一个比原始缓冲区大两倍的缓冲区。这可以创建一个 lot 大小超过最终内容的临时缓冲区对象。
这可以通过向 MemoryStream()
构造函数提供 capacity
参数从一开始就分配最大预期缓冲区大小来避免。
充其量,这类似于调用:
var bytes = authenticatableRequest.request.Content.ReadAsByteArrayAsync();
return md5.ComputeHash(bytes);
我必须为巨大的负载计算散列,所以我使用流不加载内存中的所有请求内容。问题是这段代码有什么区别:
using (var md5 = MD5.Create())
using (var stream = await authenticatableRequest.request.Content.ReadAsStreamAsync())
{
return md5.ComputeHash(stream);
}
还有那个:
using (var md5 = MD5.Create())
using (var stream = new MemoryStream())
{
await authenticatableRequest.request.Content.CopyToAsync(stream);
stream.Position = 0;
return md5.ComputeHash(stream);
}
我希望在内部有相同的行为,但也许我遗漏了什么。
I expect the same behavior internally,
为什么?我的意思是,在一种情况下,您必须将所有内容加载到内存中(因为猜猜看,您定义了一个内存流)。其他情况不一定。
第一个版本看起来不错,让散列器处理流读取。它就是为此而设计的。
ComputeHash(stream)
将在 while 循环中读取块并重复调用 TransformBlock()。
但是第二段代码会将所有内容加载到内存中,所以不要那样做:
using (var stream = new MemoryStream())
{
await authenticatableRequest.request.Content.CopyToAsync(stream);
第二个片段不仅会将所有内容加载到内存中,而且会比 HttpContent.ReadAsByteArrayAsync()
.
MemoryStream 是一个 Stream API 在 byte[]
buffer whose initial size is zero. As data gets written into it, the buffer has to be reallocated 上进入一个比原始缓冲区大两倍的缓冲区。这可以创建一个 lot 大小超过最终内容的临时缓冲区对象。
这可以通过向 MemoryStream()
构造函数提供 capacity
参数从一开始就分配最大预期缓冲区大小来避免。
充其量,这类似于调用:
var bytes = authenticatableRequest.request.Content.ReadAsByteArrayAsync();
return md5.ComputeHash(bytes);