Я написал следующий контроллер 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 ()?
Обновление: я провел дополнительное тестирование, и кажется, что HttpRequest IS фактически прерван, но, похоже, есть какая-то задержка до того, как отмена действительно произойдет. Задержка не учитывается по времени и, похоже, исходит прямо из libuv (библиотеки, на которой построен веб-сервер Kestrel). Я разместил дополнительную информацию на https://github.com/aspnet/KestrelHttpServer/issues/1103
Дополнительные обновления: проблема была перемещена в другую, так как предыдущая содержала несколько проблем. https://github.com/aspnet/KestrelHttpServer/issues/1139