route - HttpRequest no abortado(cancelado) en el abortador del navegador en ASP.NET Core MVC
tag helpers asp net core (1)
Resulta que eso simplemente usando HttpContext.RequestAborted es de hecho el camino correcto, pero debido a un error en Kestrel (el orden en que se manejaron los paquetes FIN / RST), la solicitud no se abortó en un aborto del navegador.
El error finalmente debería corregirse en Kestrel 2.0.
Vea las actualizaciones en mi pregunta para más información.
Escribí el siguiente Controlador MVC para probar la funcionalidad de cancelación:
class MyController : Controller
{
[HttpGet("api/CancelTest")]
async Task<IActionResult> Get()
{
await Task.Delay(1000);
CancellationToken token = HttpContext.RequestAborted;
bool cancelled = token.IsCancellationRequested;
logger.LogDebug(cancelled.ToString());
return Ok();
}
}
Diga, quiero cancelar la solicitud, por lo que el valor '' verdadero '' se registra en la acción del controlador anterior. Esto es posible desde el lado del servidor si el servidor implementa IHttpRequestLifetimeFeature. Afortunadamente, Kestrel sí, y esto se puede lograr de la siguiente manera:
var feature = (IHttpRequestLifetimeFeature) HttpContext.Features[typeof(IHttpRequestLifetimeFeature)];
feature.Abort();
Sin embargo, el problema es que quiero cancelar la solicitud en el lado del cliente. Por ejemplo, en el navegador. En versiones anteriores al núcleo de ASP.NET MVC / WebApi, el token de cancelación se cancelaría automáticamente si el navegador cancelara una solicitud. Ejemplo: actualiza la página un par de veces en Chrome. En la pestaña Red de las herramientas de desarrollo de Chrome, ahora puede ver que se cancela la solicitud anterior (sin terminar).
Lo que pasa es que en ASP.NET Core ejecutándose en Kestrel, solo puedo ver la siguiente entrada en el registro:
Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -4081 operación ECANCELED cancelada
Entonces, la solicitud de aborto del navegador llega y la maneja el servidor web Kestrel. Sin embargo, no afecta a la propiedad RequestAborted de HttpContext en el controlador, porque el valor '' false '' todavía está registrado por el método.
Pregunta: ¿Hay alguna forma de abortar / cancelar el método de mi controlador, de modo que la propiedad HttpContext.RequestAborted se marque como cancelada?
Quizás pueda hacer algo que se suscriba al disparador cancelado de operación de Kestrel y llamar al método IHttpRequestLifetimeFeature.Abort ()?
Actualización: Hice algunas pruebas adicionales y parece que la HttpRequest ES de hecho se canceló, pero parece que hay algún tipo de retraso antes de que la cancelación se lleve a cabo. La demora no es factorizada en el tiempo, y parece proceder directamente de libuv (la biblioteca donde se construye el servidor web Kestrel). Publiqué más información en https://github.com/aspnet/KestrelHttpServer/issues/1103
Más actualizaciones: el problema se ha movido a otro, porque el anterior contenía múltiples problemas. https://github.com/aspnet/KestrelHttpServer/issues/1139