我应该为批量异步GET请求利用多个HttpClient吗?

时间:2019-01-07 10:43:44

标签: c# http get

我有一个场景,我需要在尽可能短的时间内发出大量的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池,该池在客户端收到响应后将其释放,并仅在以下情况下创建一个新客户端:没有免费的)

1 个答案:

答案 0 :(得分:1)

我建议两个主要更改。

  1. 删除等待状态,以便可以同时进行多个下载 时间。
  2. DefaultConnectionLimit设置为更大的数字(例如50)。