我正在尝试为 ASP.NET Core 2.0 创建异步视图组件。当用户离开页面时,它将执行应该取消的操作。我有以下选择:
选项1如下所示:
public class AmazingMessageViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(string text, int wait)
{
//uses request aborted
await Task.Delay(wait, HttpContext.RequestAborted);
return View<string>(text);
}
}
选项2如下所示:
public class AmazingMessageViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(CancellationToken cancellationToken, string text, int wait)
{
await Task.Delay(wait, cancellationToken);
return View<string>(text);
}
}
这两个操作都不适用于Kestrel (看起来像个bug)。在这两种情况下,令牌都被填充(可能是因为结构?)
有什么区别,我应该使用什么?
答案 0 :(得分:2)
我知道这是一个2个月的问题,但我今天一直在努力解决这个问题并得出一些结论。
有什么区别,我应该使用什么?
根据this thread,这些是完全相同的。来自CancellationTokenModelBinder source:
var model = (object)bindingContext.HttpContext.RequestAborted;
我可以确认,我总是从HttpContext.RequestAborted
和CancellationToken
注射获得相同的值。
HttpContext.RequestAborted
的优势在于它可用于所有控制器的方法,而不仅仅是操作。 CancellationToken
参数是IMHO更好的可读性,但如果您有许多需要对令牌作出反应的嵌套方法,则通过它们的参数传播它可能变得不切实际。我会使用最适合您需求的那个。
来自同一个帖子,another post:
这仅适用于2.0而不是1.x
我知道,这不是你的情况,但它是我的。
最后,仍然来自同一个主题,特别是讨论here,有problem in IIS(特别是在与Kestrel的接口中)。 AFAIK你必须使用Kestrel和可选的(强制性的1.x)反向代理,如IIS,Apache或Nginx。我相信这是你的情况。
一些快速测试:我使用ASP .NET Core 2.0从Web API模板创建了一个项目,并修改了它创建的控制器中的第一个动作:
// GET api/values
[HttpGet]
public IEnumerable<string> Get(CancellationToken cancelToken)
{
Thread.Sleep(7000);
cancelToken.ThrowIfCancellationRequested(); // breakpoint here
return new string[] { "value1", "value2" };
}
点击F5。它启动应用程序(包括Kestrel),前面有IIS Express。发出请求并在7秒之前中止它(通过关闭浏览器选项卡)。当断点触发时,cancelToken.IsCancellationRequested
为false
。
现在,将调试配置文件从IIS Express更改为WebApplication1(或其他任何名称):
一切都像我预期的那样有效。
我也尝试使用ASP .NET Core 1.1,但没有成功。
使用ASP .NET Core 2.0的AFAIK,应该可以自己使用Kestrel。我不知道Apache或Nginx是否比IIS做得更好。