tasks run parallel getresponseasync example await async c# task-parallel-library dotnet-httpclient

run - http request async await c#



HttpClient: ¿se canceló una tarea? (4)

Funciona bien cuando tiene una o dos tareas, sin embargo, arroja un error "Se canceló una tarea" cuando tenemos más de una tarea en la lista.

List<Task> allTasks = new List<Task>(); allTasks.Add(....); allTasks.Add(....); Task.WaitAll(allTasks.ToArray(), configuration.CancellationToken); private static Task<T> HttpClientSendAsync<T>(string url, object data, HttpMethod method, string contentType, CancellationToken token) { HttpRequestMessage httpRequestMessage = new HttpRequestMessage(method, url); HttpClient httpClient = new HttpClient(); httpClient.Timeout = new TimeSpan(Constants.TimeOut); if (data != null) { byte[] byteArray = Encoding.ASCII.GetBytes(Helper.ToJSON(data)); MemoryStream memoryStream = new MemoryStream(byteArray); httpRequestMessage.Content = new StringContent(new StreamReader(memoryStream).ReadToEnd(), Encoding.UTF8, contentType); } return httpClient.SendAsync(httpRequestMessage).ContinueWith(task => { var response = task.Result; return response.Content.ReadAsStringAsync().ContinueWith(stringTask => { var json = stringTask.Result; return Helper.FromJSON<T>(json); }); }).Unwrap(); }


Hay 2 razones probables por las que se TaskCanceledException una TaskCanceledException :

  1. Algo llamado Cancel() en el CancellationTokenSource asociado con el token de cancelación antes de que se complete la tarea.
  2. Se agotó el tiempo de espera de la solicitud, es decir, no se completó dentro del intervalo de tiempo que especificó en HttpClient.Timeout .

Supongo que fue un tiempo de espera. (Si se tratara de una cancelación explícita, probablemente lo habría descubierto). Puede estar más seguro al inspeccionar la excepción:

try { var response = task.Result; } catch (TaskCanceledException ex) { // Check ex.CancellationToken.IsCancellationRequested here. // If false, it''s pretty safe to assume it was a timeout. }


Me encontré con este problema porque mi método Main() no esperaba que la tarea se completara antes de regresar, por lo que la Task<HttpResponseMessage> myTask se canceló cuando mi programa de consola salió.

La solución fue llamar a myTask.GetAwaiter().GetResult() en Main() (de esta respuesta ).


Otra posibilidad es que el resultado no sea esperado en el lado del cliente. Esto puede suceder si alguno de los métodos de la pila de llamadas no utiliza la palabra clave wait para esperar a que se complete la llamada.


Otra razón puede ser que si está ejecutando el servicio (API) y coloca un punto de interrupción en el servicio (y su código está atascado en algún punto de interrupción (por ejemplo, la solución de Visual Studio muestra Depuración en lugar de Ejecutar )). y luego presionar la API desde el código del cliente. Entonces, si el código de servicio está en pausa en algún punto de interrupción, simplemente presione F5 en VS.