【发布时间】:2017-01-27 04:41:59
【问题描述】:
我编写了以下 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 开发工具的 Network 标签中,您现在可以看到之前的(未完成的)请求被取消了。
事情是:在 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
【问题讨论】:
-
我投票决定将此问题作为题外话结束,因为问题似乎现在已得到解决
-
@Set:没关系。它确实应该在 2.0 中修复。我不能自己结束这个问题,可以吗?
-
如果您认为问题不再对其他用户有帮助,您可以删除问题,或者您可以发布自己的答案(稍后接受)并说这是 Kestrel 服务器实现中的错误已修复现在。
-
当使用 IIS 作为 Kestrel github.com/aspnet/AspNetCoreModule/issues/38 的反向代理时,还有一个问题尚未解决(截至 2.1 版)。因此,即使原始问题已得到修复,这仍然是一个非常有用的问题。
标签: asp.net-core asp.net-core-mvc cancellation kestrel-http-server