c# - postasync - HttpClient-tarea fue cancelada-¿Cómo obtener el mensaje de error exacto?
task.run async c# (3)
Tengo el siguiente código de prueba. Siempre aparece el error "La tarea fue cancelada" después de recorrer 316934 o 361992 veces.
Si no me equivoco, hay dos posibles razones por las cuales se canceló la tarea a) HttpClient obtuvo tiempo de espera ob) demasiadas tareas en cola y algunas tareas obtuvieron tiempo de espera.
No pude encontrar la documentación sobre la limitación para poner en cola las tareas. Intenté crear más de 500K tareas y sin tiempo de espera. Supongo que la razón "b" podría no ser la correcta.
Q1. ¿Hay alguna otra razón por la que me perdí?
Q2. Si es porque HttpClient timeout, ¿cómo puedo obtener el mensaje de excepción exacto en lugar de la excepción "TaskCancellation"?
Q3. ¿Cuál sería la mejor manera de arreglarlo? ¿Debería presentar el acelerador?
¡Gracias!
var _httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml");
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate");
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0");
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Charset", "ISO-8859-1");
int[] intArray = Enumerable.Range(0, 600000).ToArray();
var results = intArray
.Select(async t => {
using (HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "http://www.google.com")) {
log.Info(t);
try {
var response = await _httpClient.SendAsync(requestMessage);
var responseContent = await response.Content.ReadAsStringAsync();
return responseContent;
}
catch (Exception ex) {
log.ErrorException(string.Format("SoeHtike {0}", Task.CurrentId), ex);
}
return null;
}
});
Task.WaitAll(results.ToArray());
Console.ReadLine();
Aquí está el paso para replicar el problema.
Crear un proyecto de consola en VS 2012.
Por favor, copie y pegue mi código en Main.
Coloque el punto de interrupción en esta línea "log.ErrorException (string.Format (" SoeHtike {0} ", Task.CurrentId), ej);"
Ejecute el programa en modo de depuración. Espere unos minutos. (¿Tal vez 5 minutos?) Acabo de probar mi código y obtuve la excepción después de 3 minutos. Si tiene un violín, puede monitorear las solicitudes para que sepa que el programa aún se está ejecutando o no.
No dudes en avisarme si no puedes replicar el problema.
El valor predeterminado HttpClient.Timeout
es de 100 segundos (00:01:40). Si hace una marca de tiempo en su bloque catch
, notará que las tareas comienzan a cancelarse exactamente en ese momento. Aparentemente hay un número limitado de solicitudes HTTP que puedes hacer por segundo, otras pueden estar en cola. Las solicitudes en cola se cancelan en tiempo de espera. De todas las 600k de tareas, personalmente obtuve solo 2500 con éxito, otras fueron canceladas.
También me parece poco probable que pueda ejecutar las 600000 tareas completas. Muchos controladores de red permiten un gran número de solicitudes solo por un tiempo breve y reducen ese número a un valor muy bajo después de un tiempo. Mi tarjeta de red me permitió enviar solo 921 solicitudes en 36 segundos y reduje esa velocidad a solo una solicitud por segundo. A esa velocidad, llevará una semana completar todas las tareas.
Si puede eludir esa limitación, asegúrese de compilar el código para la plataforma de 64 bits ya que la aplicación está muy hambrienta de memoria.
No elimine la instancia de HttpClient que está utilizando. Raro, pero solucionó este problema.
Solo quería compartir. He tenido un código similar para probar la carga de nuestros servidores, y es muy probable que sus solicitudes se agoten. Puede configurar el tiempo de espera para su solicitud http al máximo y ver si cambia algo para usted. Traté de golpear nuestros servidores creando varios hilos. Y aumentó los hits, pero eventualmente todos terminarían el tiempo de espera. Y tampoco puedes establecer un tiempo de espera cuando los tocas en otro hilo.