HttpRequest не прерван (отменен) при прерывании браузера в ASP.NET ядро MVC
Я написал следующий контроллер MVC для проверки функциональности отмены:
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();
}
}
скажем, я хочу отменить запрос, поэтому значение'правда ' регистрируется в действии контроллера выше. Это возможно на стороне сервера, если сервер реализует IHttpRequestLifetimeFeature. К счастью, Kestrel делает, и это может быть выполнено следующим образом:
var feature = (IHttpRequestLifetimeFeature) HttpContext.Features[typeof(IHttpRequestLifetimeFeature)];
feature.Abort();
проблема в том, что я хочу отменить запрос на стороне клиента. Например, в браузере. В pre-core версиях ASP.NET MVC / WebApi маркер отмены будет автоматически отменен, если браузер прервал запрос. Пример: обновите страницу пару раз в Chrome. На вкладке Сеть инструментов Chrome dev теперь вы можете увидеть предыдущий (незавершенный) запрос будет отменен.
дело в том, что: в ASP.NET ядро работает на Kestrel, я вижу только следующую запись в журнале:
Microsoft.AspNetCore.Сервер.Пустельга.Внутренний.Сетевой.UvException: Ошибка -4081 операция ECANCELED отменена
таким образом, запрос на прерывание из браузера поступает и обрабатывается веб-сервером Kestrel. Однако это не влияет на свойство RequestAborted HttpContext в контроллере, потому что значение'false по-прежнему регистрируется методом.
вопрос: Есть ли способ прервать / отменить мой контроллер метод, таким образом, что объект HttpContext.Свойство RequestAborted будет помечено как отмененное?
возможно, я могу сделать что-то, что подпишется на триггер отмены операции Kestrel и вызовет IHttpRequestLifetimeFeature.Прервать() метод?
обновление: Я сделал еще несколько тестов, и кажется, HttpRequest IS на самом деле прервано, но, похоже, есть какая-то задержка до отмены на самом деле происходит. Задержка не время-учитывается и, кажется, приходит прямо из libuv (библиотека, где веб-сервер Kestrel построен поверх). Я опубликовал больше информации оhttps://github.com/aspnet/KestrelHttpServer/issues/1103
больше обновлений: Проблема была перенесена на другую, потому что предыдущая содержала несколько проблем. https://github.com/aspnet/KestrelHttpServer/issues/1139
1 ответов
оказывается, что это просто использование HttpContext.RequestAborted действительно правильный способ, но из-за ошибки в Kestrel (порядок, в котором обрабатывались пакеты FIN/RST) запрос не был прерван в браузере.
ошибка, наконец, должна быть исправлена в Kestrel 2.0.
см. обновления в моем вопросе для получения дополнительной информации.