Windows上的.NET核心3.1控制台应用程序,我试图弄清楚为什么httpClient.Timeout
在使用HttpCompletionOption.ResponseHeadersRead后获取内容时似乎不起作用
static async Task Main(string[] args)
{
var httpClient = new HttpClient();
// if using HttpCompletionOption this timeout doesn't work
httpClient.Timeout = TimeSpan.FromSeconds(5);
var uri = new Uri("http://brokenlinkcheckerchecker.com/files/200MB.zip");
// will not timeout
//using var httpResponseMessage = await httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead);
// will timeout after 5s with a TaskCanceledException
var httpResponseMessage = await httpClient.GetAsync(uri);
Console.WriteLine($"Status code is {httpResponseMessage.StatusCode}. Press any key to get content");
Console.ReadLine();
Console.WriteLine("getting content");
var html = await httpResponseMessage.Content.ReadAsStringAsync();
Console.WriteLine($"finished and length is {html.Length}");
}
也尝试过CancellationToken
// will not timeout
var cts = new CancellationTokenSource(5000);
using var httpResponseMessage = await httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead,
cts.Token);
和ReadAsStreamAsync
// will not timeout
using (Stream streamToReadFrom = await httpResponseMessage.Content.ReadAsStreamAsync())
{
string fileToWriteTo = Path.GetTempFileName();
using (Stream streamToWriteTo = File.Open(fileToWriteTo, FileMode.Create))
{
await streamToReadFrom.CopyToAsync(streamToWriteTo);
}
}
我从这篇伟大的文章中了解到了HttpCompletionOption
:https://www.stevejgordon.co.uk/using-httpcompletionoption-responseheadersread-to-improve-httpclient-performance-dotnet
使用@StephenCleary下面的@StephenCleary答案更新,将cancellationToken传递到CopyToAsync
方法中,现在,这个方法与预期的一样工作。
我已经包含了下面更新的代码,这些代码显示了复制到一个MemoryStream
中然后放入一个字符串中,我发现要找到如何做到这一点很棘手。对于我的用例来说,这很好。
string html;
await using (var streamToReadFrom = await httpResponseMessage.Content.ReadAsStreamAsync())
await using (var streamToWriteTo = new MemoryStream())
{
await streamToReadFrom.CopyToAsync(streamToWriteTo, cts.Token);
// careful of what encoding - read from incoming MIME
html = Encoding.UTF8.GetString(streamToWriteTo.ToArray());
}
发布于 2020-07-20 13:36:00
我希望HttpClient.Timeout
只应用于请求的GetAsync
部分。HttpCompletionOption.ResponseHeadersRead
的意思是“在读取响应头时考虑Get
完成”,因此它是完整的。所以问题是它不适用于从溪流中阅读。
我建议使用波莉超时而不是HttpClient.Timeout
;Polly是一个通用库,可用于超时任何操作。
如果此时不想使用Polly,可以将CancellationToken
传递给Stream.CopyToAsync
。
https://stackoverflow.com/questions/62994860
复制相似问题