understanding - ¿HttpClient(C#) falla en muchas solicitudes asincrónicas?
task.run async c# (2)
Ajuste ServicePointManager.DefaultConnectionLimit
. Para solicitudes masivamente concurrentes, puede configurarlo en int.MaxValue
.
Estoy usando HttpClient para hacer asincrónicamente muchas solicitudes a una API externa. Espero todas las solicitudes para completar, luego uso las respuestas en otro código. Mi problema es que si hago demasiadas solicitudes, mi código arroja una excepción cuando uso la Tarea. Cuando todo espera.
Este código finalmente se ejecutará en paralelo, lo que significa que haré muchos conjuntos de estas solicitudes asíncronas al mismo tiempo (es decir, 10 conjuntos de 200 solicitudes de sincronización). He instanciado un HttpClient que estoy usando con .NET 4.5 modificadores async / await como este:
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...
}
}
Sigo recibiendo una excepción TaskCanceledException. Después de analizar esto, vi que posiblemente se trata de un problema de tiempo de espera. No tengo ni idea de cómo arreglarlo. Intenté agrupar mis solicitudes en 100 solicitudes antes de usar la Tarea. Cuando todo y repetir, lo cual funcionó. Luego, cuando ejecuté eso en paralelo con tres conjuntos de 100 solicitudes, falla. ¿Me estoy perdiendo algo? ¿Alguien tiene alguna idea de esto?
Es probable que TaskCanceledException
se deba a que su HttpClient
se eliminó antes de que se complete una solicitud en cuestión. Sospecho que el código que le da la excepción no es el mismo que el ejemplo que ha publicado, ya que no se compilará.
Lo siguiente funciona bien para mí con hasta 2000 solicitudes:
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:
}
}
Por lo tanto, es probable que haya otro problema que tenga que no haya proporcionado suficientes detalles para que nadie lo descubra.
Además de los problemas que he comentado al usar Parallel.ForEach
: ForEach
está bloqueando, por lo que se bloqueará su UI.