【发布时间】:2021-06-30 10:47:07
【问题描述】:
我在使用 C#HttpClient 时遇到了一个奇怪的情况。我正在尝试使用GetAsync 中的HttpCompletionOption.ResponseHeadersRead 选项来尽快获取没有内容的响应标头。但是在下载文件时,我在await GetAsync,直到整个内容都通过网络下载(我用 Fiddler 进行了检查)。我附上了一个下载 1Gb 测试文件的示例代码。示例应用程序将在await client.GetAsync 中挂起,直到通过网络接收到所有文件内容。当标头完成接收并且不等待通过网络完成内容传输时,如何重新获得控制权?
using System;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
private const int HttpBufferSize = 81920;
private static async Task Main(string[] args)
{
var url = new Uri("http://212.183.159.230/1GB.zip");
await DownloadFileAsync(@"C:\1GB.zip", url, CancellationToken.None).ConfigureAwait(false);
}
private static async Task DownloadFileAsync(string filePath, Uri fileEndpoint,
CancellationToken token)
{
using var client = new HttpClient();
using var response = await client.GetAsync(fileEndpoint, HttpCompletionOption.ResponseHeadersRead, token).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
await using var contentStream = await response.Content.ReadAsStreamAsync(token).ConfigureAwait(false);
await using var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None);
await contentStream.CopyToAsync(stream, HttpBufferSize, token).ConfigureAwait(false);
}
}
【问题讨论】:
-
你应该使用
HEAD而不是GET请求。 -
@Riddell 这就是 httpcompletionoption 在 Get 调用中所做的我认为 stackoverflow.com/questions/16416699/…
-
@sommmen 从内存中,
GetAsync始终是GET请求,因为它是SendAsync和HttpMethod.Get的包装器。 -
@Riddell 感谢您的解释!
-
我无法使用提供的代码重现这一点。对我来说,代码在
GetAsync上没有等待很长时间;正如预期的那样,它在CopyToAsync上等待了很长时间。有没有可能是 Fiddler 误导了你?
标签: c# dotnet-httpclient