【发布时间】:2019-11-19 00:16:42
【问题描述】:
我使用一个 httpclient 发出约 20 个 http get 请求,这个 httpclient 是长期存在的,这意味着它没有被打包到 using 语句中。由于网络服务通常非常快(响应时间约为 200 毫秒),因此我将超时设置为 5 秒。
现在我遇到了问题,如果一个请求遇到该超时,所有其他请求都会被取消。这是正常行为吗?
这是我用来进行并发调用的代码
public async Task GetAll()
{
await Task.WhenAll(x => x.Select(xx => GetData(xx.Id));
}
调用api的代码:
public async Task GetData(int id)
{
string payload = "";
try
{
var resp = await base.GetAsync($"/apis/v2/getdata/{id}");
if (!resp.IsSuccessStatusCode)
Console.WriteLine("Error");
payload = await resp.Content.ReadAsStringAsync();
Console.WriteLine(payload);
}
catch (System.Exception ex)
{
Console.WriteLine("Error");
}
}
我的基础 HttpClient 类
public class MyHttpClient : System.Net.Http.HttpClient
{
public Logger Log { get; set; }
}
如果我按顺序运行任务一切正常,但是当我并行运行它们并且一个任务超时时,所有其他未完成的任务都将被取消。
【问题讨论】:
-
这不是您的实际代码。首先,它甚至无法编译,因为它缺少
async修饰符。base这里是什么?base.GetAsync是做什么的? -
如果将
ServicePointManager.DefaultConnectionLimit设置为 20,是否可以解决问题? (因为 .Net Framework 中默认限制为 2,参考:blogs.msdn.microsoft.com/timomta/2017/10/23/…) -
@Stefan D'oh,我没有看到这是 2 个不同的功能。不过,我们需要知道
base是什么,不知道你认为它是什么HttpClient(base是保留字,所以它不能是变量名) -
@DavidG GetData 是我的 HttpClient 类中的一个方法,它只是派生自 System.Net.HttpClient,因此 base.GetAsync 仅调用 System.Net.HttpClient.GetAsync 方法。我还没有尝试过 DefaultConnectionLimit。我首先想了解一个请求超时而其他请求仍在运行时 HttpClient 的行为。
-
@ManuelBleimuth 每个域有 2 个并发连接的默认限制,由所有浏览器和 .NET 本身强制执行。您可以在 HttpClientHandler 设置中覆盖。另一方面,可能是 API 由于阻塞数据库连接、锁定或低效编码而阻塞。
标签: c# task dotnet-httpclient