我有一个场景,我需要在尽可能短的时间内发出大量的GET请求(大约1000个)。
我知道通常最好保留一个客户端并尽可能地重用它:
// Create Single HTTP Client
HttpClient client = new HttpClient();
// Create all tasks
for (int x = 0; x < 1000; x++)
{
tasks.Add(ProcessURLAsync($"https://someapi.com/request/{x}", client, x));
}
// wait for all tasks to complete.
Task.WaitAll(tasks.ToArray());
...
static async Task<string> ProcessURLAsync(string url, HttpClient client, int x)
{
var response = await client.GetStringAsync(url);
ParseResponse(response.Result, x);
return response;
}
但是,完成所有请求大约需要70秒。
另一方面,如果我预先创建了多个客户端并在其中分配请求,则大约需要3秒钟才能完成:
// Create arbitrary number of clients
while (clients.Count < maxClients)
{
clients.Add(new HttpClient());
}
// Create all tasks
for (int x = 0; x < 1000; x++)
{
tasks.Add(ProcessURLAsync(
$"https://someapi.com/request/{x}", clients[x % maxClients], x));
}
// Same same code as above
由于所请求数据的性质,我需要使结果保持顺序或传递与请求关联的索引。
假设无法更改API以更好地格式化请求的数据,并且所有请求必须在继续之前完成,这是明智的解决方案,还是我缺少更聪明的选择?
(为简洁起见,我使用了任意数量的HttpClient
,而我将创建一个HttpClient
池,该池在客户端收到响应后将其释放,并仅在以下情况下创建一个新客户端:没有免费的)