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.

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