asp.net-core – 在ASP.NET Core MVC中,浏览器中止没有中止(取消)HttpRequest

我编写了以下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工具的“网络”选项卡中,您现在可以看到取消上一个(未完成的)请求.

问题是:在Kestrel上运行的ASP.NET Core中,我只能在日志中看到以下条目:

Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException:
Error -4081 ECANCELED operation canceled

因此,来自浏览器的中止请求到达并由Kestrel网络服务器处理.但它不会影响控制器中HttpContext的RequestAborted属性,因为该方法仍会记录值’false’.

题:
有没有办法中止/取消我的控制器的方法,以便将HttpContext.RequestAborted属性标记为已取消?

也许我可以做一些订阅Kestrel的操作取消触发器并调用IHttpRequestLifetimeFeature.Abort()方法的东西?

更新:
我做了一些进一步的测试,似乎HttpRequest IS实际上已经中止了,但在实际取消之前似乎有某种延迟.延迟不是时间因素,似乎直接来自libuv(Kestrel网络服务器构建在其上的库).我在https://github.com/aspnet/KestrelHttpServer/issues/1103上发布了更多信息

更多更新:
问题已转移到另一个问题,因为前一个问题包含多个问题. https://github.com/aspnet/KestrelHttpServer/issues/1139

解决方法

事实证明,简单地使用HttpContext.RequestAborted确实是正确的方法,但是由于Kestrel中的错误(处理FIN / RST包的顺序),请求在浏览器中止时没有中止.

最终应该在Kestrel 2.0中修复该错误.

有关详细信息,请参阅我的问题中的更新.

相关文章

本文将从上往下,循序渐进的介绍一系列相关.NET的概念,先从...
基于 .NET 的一个全新的、好用的 PHP SDK + Runtime: Pe...
.NET 异步工作原理介绍。
引子 .NET 6 开始初步引入 PGO。PGO 即 Profile Guided Opti...
前言 2021/4/8 .NET 6 Preview 3 发布,这个版本的改进大多来...
前言 开头防杠:.NET 的基础库、语言、运行时团队从来都是相...