Nic*_*ler 14 cancellation asp.net-core-mvc kestrel-http-server asp.net-core
我编写了以下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();
}
}
Run Code Online (Sandbox Code Playgroud)
说,我想取消请求,因此在上面的控制器操作中记录值' true '.如果服务器实现IHttpRequestLifetimeFeature,这可能是服务器端.幸运的是,Kestrel确实如此,这可以通过以下方式实现:
var feature = (IHttpRequestLifetimeFeature) HttpContext.Features[typeof(IHttpRequestLifetimeFeature)];
feature.Abort();
Run Code Online (Sandbox Code Playgroud)
但问题是我想在客户端取消请求.例如,在浏览器中.在ASP.NET MVC/WebApi的预核版本中,如果浏览器中止请求,则取消令牌将自动取消.示例:在Chrome中多次刷新页面.在chrome dev工具的"网络"选项卡中,您现在可以看到取消上一个(未完成的)请求.
问题是:在Kestrel上运行的ASP.NET Core中,我只能在日志中看到以下条目:
Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException:错误-4081 ECANCELED操作已取消
因此,来自浏览器的中止请求到达并由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 中得到修复。
请参阅我的问题中的更新以获取更多信息。
归档时间: |
|
查看次数: |
2594 次 |
最近记录: |