Use un único CancellationToken para las cabeceras y el cuerpo de .NET HttpClient
Lleve el CancellationToken de la solicitud tanto por la preparación de la respuesta de HttpClient como por la lectura del cuerpo, en lugar de medir solo la espera del llamador.
Un cronómetro puede dejar de esperar mientras la solicitud HTTP continúa. Proporcione cancelación a la propia operación cuando un intento a través de un proxy tenga un presupuesto previsto.
Para una aplicación .NET moderna con un HttpClient configurado para proxy existente:
using var budget = new CancellationTokenSource(TimeSpan.FromSeconds(5));
using var response = await client.GetAsync(
targetUrl,
HttpCompletionOption.ResponseHeadersRead,
budget.Token);
response.EnsureSuccessStatusCode();
string body = await response.Content.ReadAsStringAsync(budget.Token);
El mismo presupuesto comienza antes de la preparación y permanece activo mientras se lee el cuerpo. ResponseHeadersRead devuelve el control después de las cabeceras, por lo que el tiempo de espera de finalización propio de HttpClient no define por sí solo el presupuesto posterior de lectura del cuerpo.
Mantenga la cancelación separada del estado HTTP y de los errores de transporte. Una OperationCanceledException puede provenir del token suministrado o de otro tiempo de espera configurado; inspeccione la fuente de cancelación aplicable en lugar de informar cada fallo como un proxy muerto.
Reutilice el cliente que posee esta ruta de proxy. Cancelar un intento no tiene por qué significar reconstruir todo un grupo de conexiones para cada solicitud posterior.
El ejemplo almacena en búfer un cuerpo de respuesta finito. Una descarga en streaming debería pasar el token por su bucle de copia de flujo y liberar la respuesta en cada ruta de salida.
La cancelación expresa una política de operación, no una promesa exacta de reloj de pared para cada acción subyacente de la plataforma. Evite sustituirla por un bucle de sondeo sin fin sobre Task.IsCompleted.