asp.net-mvc - HttpContext.RequestAborted 和 CancellationToken 参数有什么区别?

标签 asp.net-mvc .net-core kestrel asp.net-core-viewcomponent

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

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

有什么区别以及我应该使用什么?

最佳答案

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

<小时/>

有什么区别以及我应该使用什么?

根据this thread这些是完全相同的事情。来自 CancellationTokenModelBinder source :

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

我可以确认,我总是从 HttpContext.RequestAbortedCancellationToken 注入(inject)中获得相同的值。

HttpContext.RequestAborted 的优点是它在所有 Controller 的方法中都可用,而不仅仅是操作。恕我直言,CancellationToken 参数的可读性更好,但如果您有许多需要对 token 使用react的嵌套方法,那么通过它们的参数传播它可能会变得不切实际。我只会使用更适合您需求的那个。

<小时/>

来自同一线程,another post :

This only works in 2.0 not in 1.x

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

<小时/>

最后,仍然来自同一个线程,特别是讨论 here ,有一个problem in IIS (特别是在它与 Kestrel 的接口(interface)中)。据我所知,您必须使用 Kestrel 和可选的(1.x 强制)反向代理,例如 IIS、Apache 或 Nginx。我相信这就是您的情况。

<小时/>

一些快速测试:我使用 ASP .NET Core 2.0 从 Web API 模板创建了一个项目,并修改了它创建的 Controller 中的第一个操作:

// GET api/values
[HttpGet]
public IEnumerable<string> Get(CancellationToken cancelToken)
{
    Thread.Sleep(7000);
    cancelToken.ThrowIfCancellationRequested(); // breakpoint here
    return new string[] { "value1", "value2" };
}

按 F5。它启动前面有 IIS Express 的应用程序(包括 Kestrel)。发出请求并在 7 秒之前中止(通过关闭浏览器选项卡)。断点触发时,cancelToken.IsCancellationRequestedfalse

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

enter image description here

一切都按我的预期进行。

我也对 ASP .NET Core 1.1 进行了相同的尝试,但没有成功。

<小时/>

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

关于asp.net-mvc - HttpContext.RequestAborted 和 CancellationToken 参数有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47153525/

相关文章:

c# - 为什么具有 1 和 2 秩的非零基数组具有不同的类型?

javascript - 如何将 RTF 字符串转换为 Markdown 字符串(以及转换回来)(C# .NET Core 或 JS)

c# - EasynetQ 总线。订阅未触发 - 抛出 "messageType must not be null"

angular - 为什么 Asp net Core 会为我的 Angular Spa dist 文件的请求返回 index.html?

linux - 从 appsettings.json 加载 SSL 证书

javascript - ASP.NET mcv : How to send javascript array to c# controller

asp.net-mvc - 使用 ASP.NET MVC 自定义路由以进行分面搜索 [从 QueryString 到 Route ]

ubuntu - Asp.Net Core Web API 应用程序 : how to change listening address?

c# - 为什么我会收到 "The modifier ' virtual'is not valid for this item“错误?

asp.net-mvc - 在子域中运行 ASP.NET MVC 会使 Html.ActionLink 呈现断开的链接