Я написал следующий 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