14

我正在尝试为ASP.NET Core 2.0创建一个异步视图组件。当用户离开页面时,它将执行应取消的操作。我有以下选择:

  1. 使用 HttpContext.RequestAborted
  2. 使用 CancellationToken 参数
  3. 我也可以链接令牌

选项 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(看起来像一个错误)。在这两种情况下,令牌都被填充(可能是因为结构?)

有什么区别,我应该使用什么?

4

1 回答 1

10

我知道这是一个 2 个月前的问题,但我今天也一直在努力解决这个问题并得出了一些结论。


有什么区别,我应该使用什么?

根据这个线程,这些是完全相同的东西。从CancellationTokenModelBinder 来源

var model = (object)bindingContext.HttpContext.RequestAborted;

我可以确认,我总是从注入中HttpContext.RequestAborted得到相同的值。CancellationToken

的优点HttpContext.RequestAborted是它在所有控制器的方法中都可用,而不仅仅是动作。恕我直言,该CancellationToken参数可读性更好,但如果您有许多需要对令牌做出反应的嵌套方法,则通过它们的参数传播它可能变得不切实际。我只会使用更适合您需求的那个。


从同一个线程,另一个帖子

这仅适用于 2.0 而不是 1.x

我知道,这不是你的情况,但它是我的。


最后,仍然来自同一个线程,尤其是这里的讨论, 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.IsCancellationRequestedfalse断点触发的时候。

现在,将调试配置文件从 IIS Express 更改为 WebApplication1(或其他名称):

在此处输入图像描述

一切都按我的预期工作。

我也尝试过使用 ASP .NET Core 1.1,但没有成功。


使用 ASP .NET Core 2.0 的 AFAIK,应该能够单独使用 Kestrel。我不知道 Apache 或 Nginx 是否比 IIS 做得更好。

于 2018-01-08T16:22:31.567 回答