HttpClient(C#)在许多异步请求上失败了吗?

时间:2014-02-04 16:36:11

标签: c# asynchronous .net-4.5 dotnet-httpclient async-await

我正在使用HttpClient异步向外部api发出许多请求。我等待所有请求完成,然后在其他代码中使用响应。我的问题是,如果我发出太多请求,当我使用Task.WhenAll等待时,我的代码会引发异常。

此代码最终将并行运行,我的意思是我将同时执行多组这些异步请求(即10组200个异步请求)。我已经实例化了一个HttpClient,我正在使用.NET 4.5异步/等待修饰符,如下所示:

using (var client = new HttpClient())
{
    // make a list of tasks
    List<Task<HttpResponseMessage>> taskList;
    List<MyData> replies;
    for (int i = 0; i < MAX_NUMBER_REQUESTS; i++)
    {
        taskList.Add(client.GetAsync(externalUri);
    }

    List<HttpResponseMessage> responses = await Task.WhenAll(taskList);

    // read each response after they have returned
    foreach (var response in responses)
    {
        var reader = new System.IO.StreamReader(await response.Content.ReadAsStreamAsync());
        replies.Add(JsonConvert.DeserializeObject<MyData>(reader.ReadToEnd()));
        reader.Close();
} 

    foreach (var reply in replies)
    {
        // do something with the response from the external api call...
    }
}

我不断收到TaskCanceledException。在调查之后,我看到这可能是一个超时问题。我不知道如何解决它。在尝试使用Task.WhenAll并重复之前,我试图在100个请求中批量处理我的请求。然后,当我与三组100个请求失败并行运行时。我错过了什么,有没有人对此有任何见解?

2 个答案:

答案 0 :(得分:9)

调整ServicePointManager.DefaultConnectionLimit。对于大量并发请求,您只需将其设置为int.MaxValue

答案 1 :(得分:2)

TaskCanceledException可能是由于您的HttpClient在您的相关请求完成之前被处理掉了。我怀疑给你异常的代码与你发布的样本不一样,因为它不会编译?

以下适用于我的最多2000个请求:

using (var client = new HttpClient())
{
    List<Task<HttpResponseMessage>> taskList = new List<Task<HttpResponseMessage>>();
    List<MyData> replies = new List<MyData>();
    for (var i = 0; i < MAX_NUMBER_REQUESTS; ++i)
    {
        taskList.Add(client.GetAsync(externalUrl));
    }
    var responses = await Task.WhenAll(taskList);

    foreach (var m in responses)
    {
        using (var reader = new StreamReader(await m.Content.ReadAsStreamAsync()))
        {
            replies.Add(JsonConvert.DeserializeObject<MyData>(reader.ReadToEnd()));
        }
    }

    foreach (var reply in replies)
    {
        // TODO:        
    }
}

所以,你可能还有其他一些问题,你没有提供足够的细节供任何人弄明白。

除了我使用Parallel.ForEach评论的问题之外:ForEach正在屏蔽,因此您的用户界面将被屏蔽。