HttpClient SendAsync 和 HttpContent CopyToAsync

问题描述 投票:0回答:1

我正在使用 HttpClient 下载文件。我想知道资源实际上是在什么时候通过网络下载的(想计算下载率)? 创建客户端后,我使用 SendAsync 并立即从响应访问 HttpContent 并使用内容的 CopyToAsync 方法复制到文件。 是在调用 SendAsync 时还是在调用 CopyToAsync 时下载文件? 这是 .Net 4.6.2

c# .net dotnet-httpclient .net-4.6.2
1个回答
3
投票

默认情况下,

SendAsync
使用
ResponseContentRead
HTTP 完成选项,这意味着响应在返回的任务完成之前完全缓存在内存中,因此,读取响应的内容只是从缓存的内存数据中复制。这样做的好处是允许您以增加内存使用量为代价从响应中多次读取。

这样做的副作用是,当您开始从流中读取时,文件已经完全下载,这意味着您对下载率所做的任何计算都将毫无意义。

如果要在下载文件时复制文件,请将

ResponseHeadersRead
传递给
SendAsync
。这将使
SendAsync
返回的任务在读取标题后立即完成:

using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
// here, response only contains the response headers
response.EnsureSuccessStatusCode();
using var stream = await response.Content.ReadAsStreamAsync();
// start reading from stream
await stream.CopyToAsync(file); // download and write at the same time

但是,如果你这样做,你 have 在完成阅读后处理响应(最好使用

using
语句,如上所示)以便尽快关闭连接,如使用
ResponseHeadersRead 
将使响应保留到操作系统资源,直到处理(或最终确定)为止,这与
ResponseContentRead
不同,客户端可以在下载完成后立即释放这些资源。在实践中,这并不是真正的问题,因为您应该始终在一次性物品超出范围之前将其处理掉,但这仍然需要牢记。

© www.soinside.com 2019 - 2024. All rights reserved.