Подтвердить что ты не робот

HttpRequest не отменен (отменен) при отмене браузера в ASP.NET Core 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();
    }
}

Скажем, я хочу отменить запрос, поэтому значение " true" зарегистрировано в действии контроллера выше. Это возможно на стороне сервера, если сервер реализует IHttpRequestLifetimeFeature. К счастью, Kestrel делает это, и это можно сделать следующим образом:

var feature = (IHttpRequestLifetimeFeature) HttpContext.Features[typeof(IHttpRequestLifetimeFeature)];
feature.Abort();

Однако проблема заключается в том, что я хочу отменить запрос на стороне клиента. Например, в браузере. В предварительных версиях ASP.NET MVC/WebApi маркер отмены автоматически отменяется, если браузер прервал запрос. Пример: несколько раз обновите страницу в Chrome. На вкладке "Сеть" инструментов chrome dev вы можете увидеть отмену предыдущего (незавершенного) запроса.

Дело в том, что в ASP.NET Core, запущенном на Kestrel, я могу видеть только следующую запись в журнале:

Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Ошибка -4081 Отменена операция ECANCELED

Таким образом, запрос прерывания из браузера поступает и обрабатывается веб-сервером Kestrel. Однако он не влияет на свойство RequestAborted HttpContext в контроллере, потому что значение false "все еще регистрируется методом.

Вопрос: Есть ли способ прервать/отменить мой метод контроллера, чтобы свойство HttpContext.RequestAborted было отмечено как отмененное?

Возможно, я могу сделать что-то, что подписалось бы на операцию отмены Kestrel и вызвать метод IHttpRequestLifetimeFeature.Abort()?

Update: Я провел некоторое тестирование, и кажется, что HttpRequest IS фактически прерван, но, похоже, какая-то задержка до того, как аннулирование действительно происходит. Задержка не учитывается во времени и, кажется, идет прямо из libuv (библиотека, на которой веб-сервер Kestrel строится поверх). Я разместил дополнительную информацию о https://github.com/aspnet/KestrelHttpServer/issues/1103

Дополнительные обновления: Проблема перенесена на другую, поскольку предыдущая проблема состояла из нескольких проблем. https://github.com/aspnet/KestrelHttpServer/issues/1139

4b9b3361

Ответ 1

Оказывается, что просто использование HttpContext.RequestAborted действительно правильно, но из-за ошибки в Kestrel (порядок обработки пакетов FIN/RST) запрос не прерывался при прерывании браузера.

Теперь ошибка должна быть исправлена ​​в Kestrel 2.0.

Для получения дополнительной информации см. обновления в моем вопросе.