gpt4 book ai didi

http - 使用 HttpClient 阻止下载整个远程资源?

转载 作者:可可西里 更新时间:2023-11-01 17:27:25 25 4
gpt4 key购买 nike

在 UWP 下,低级 HttpWebRequest 类及其同类已被弃用,并且 the official recommendation就是使用System.Net.Http.HttpClient

但是,HttpClient 实现中似乎存在明显的疏忽或错误:API 似乎没有提供一种方法来向不会自动发出请求的远程 URI下载整个远程资源(在 GET 请求的情况下)以允许延迟评估响应流。

The documentation for the HttpClient.GetAsync() method说:

This operation will not block. The returned task object will complete after the whole response (including content) is read.

预先声明在请求完成之前将下载整个远程资源。有一个 HttpCompletionOption 参数,如果指定了 HttpCompletionOption.ResponseHeadersRead,理论上可以解决此问题,记录如下:

The operation should complete as soon as a response is available and headers are read. The content is not read yet.

但是,无论指定了哪个 HttpCompletionOption,在所有情况下,HttpClient.GetAsync() 都会分配完整的 ContentLength 字节过程中的响应(在内存中!一次全部!没有任何限制检查!)。自然,这有点疯狂,也是一个真正的问题。

在我的特殊情况下,我只想从不支持 http 范围 header 的服务器读取数 GB 远程资源的前几 kb。这通常是一个“不费吹灰之力”的操作:只需创建 Web 请求,从响应流中读取直到您满意为止,然后关闭响应并开始您的快乐之旅。

这似乎不是默认 HttpClient API 的选项。是否有一种简单的解决方法,不涉及使用原始套接字制作我自己的 HTTP 请求?

最佳答案

in all cases, HttpClient.GetAsync() appears to allocate the complete ContentLength bytes of the response (in memory! all at once! without any limit checking!)

对于 HttpCompletionOption.ResponseHeadersRead 选项,情况并非如此。

就像使用古老的 HttpWebRequest 类一样,您可以打开响应流并读取几个字节,然后丢弃响应。这是 an example .

这是我的实验:(我改用 Windows.Web.Http.HttpClient,但 System.Net.Http.HttpClient 提供了类似的 API)

private HttpClient httpClient = new HttpClient();
private CancellationTokenSource cts = new CancellationTokenSource();


private async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
Uri resourceAddress = new Uri("http://somewhere/gigabyte.zip");

try
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, resourceAddress);

// Do not buffer the response.
HttpResponseMessage response = await httpClient.SendRequestAsync(
request,
HttpCompletionOption.ResponseHeadersRead).AsTask(cts.Token);

using (Stream responseStream = (await response.Content.ReadAsInputStreamAsync()).AsStreamForRead())
{
int read = 0;
byte[] responseBytes = new byte[1000];
do
{
read = await responseStream.ReadAsync(responseBytes, 0, responseBytes.Length);
break;
} while (read != 0);
}
}
catch (TaskCanceledException)
{
}
catch (Exception ex)
{
}
finally
{
}
}

关于http - 使用 HttpClient 阻止下载整个远程资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44398702/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com