HttpContext.RequestAborted 和 CancellationToken 参数有什么区别? [英] What's the difference between HttpContext.RequestAborted and CancellationToken parameter?

查看:41
本文介绍了HttpContext.RequestAborted 和 CancellationToken 参数有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

选项 1 如下所示:

public class AmazingMessageViewComponent : ViewComponent{公共异步任务InvokeAsync(字符串文本,int 等待){//使用请求中止等待 Task.Delay(等待,HttpContext.RequestAborted);返回视图<字符串>(文本);}}

选项 2 如下所示:

public class AmazingMessageViewComponent : ViewComponent{公共异步任务InvokeAsync(CancellationToken 取消令牌,字符串文本,整数等待){等待任务.延迟(等待,取消令牌);返回视图<字符串>(文本);}}

这两个操作都不适用于 Kestrel(看起来像一个错误).在这两种情况下,令牌都被填充(可能是因为结构?)

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

解决方案

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

<小时>

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

根据

一切都如我所愿.

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

<小时>

AFAIK 和 ASP .NET Core 2.0,应该可以单独使用 Kestrel.不知道是Apache还是Nginx比IIS做的好.

I'm trying to create an async view component for ASP.NET Core 2.0. It will do an action that should be cancelled when the user navigates away from the page. I've got the following options:

  1. Using the HttpContext.RequestAborted
  2. Using a CancellationToken parameter
  3. I could also chain the tokens

Option 1 looks like this:

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);
    }
}

Option 2 looks like this:

public class AmazingMessageViewComponent : ViewComponent
{
    public async Task<IViewComponentResult> InvokeAsync(CancellationToken cancellationToken, string text, int wait)
    {
        await Task.Delay(wait, cancellationToken);
        return View<string>(text);
    }
}

Both action do not work with Kestrel (looks like a bug). In both cases the tokens are filled (maybe because of struct?)

What is the difference and what should I use?

解决方案

I know this is a 2 months old issue, but I have been struggling with this today too and came to some conclusions.


What is the difference and what should I use?

According to this thread these are exactly the same things. From CancellationTokenModelBinder source:

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

I can confirm, I always get the same values from HttpContext.RequestAborted and CancellationToken injection.

Advantage of HttpContext.RequestAborted is that it is available in all controller's methods, not just actions. The CancellationToken parameter is IMHO better readable but if you have a number of nested methods that need to react to the token, it may become impractical to propagate it through their parameters. I would just use the one that better suits your needs.


From the same thread, another post:

This only works in 2.0 not in 1.x

I know, this is not your case but it was mine.


Finally, still from the same thread and especially discussion here, there's a problem in IIS (specifically in its interface with Kestrel). AFAIK you have to use Kestrel and optionally (mandatory for 1.x) a reverse proxy such as IIS, Apache or Nginx. I believe this is your case.


Some quick testing: I created a project from Web API template using ASP .NET Core 2.0 and modified the first action in the controller it created:

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

Hit F5. It starts the app (including Kestrel) with IIS Express in front of it. Make the request and abort it (by closing a browser tab) before the 7 seconds. cancelToken.IsCancellationRequested is false when the breakpoint triggers.

Now, change the debug profile from IIS Express to WebApplication1 (or whatever it is called):

Everything works as expected for me.

I did also try the same with ASP .NET Core 1.1 but with no success.


AFAIK with ASP .NET Core 2.0, one should be able to use Kestrel on its own. I don't know if Apache or Nginx are doing better than IIS.

这篇关于HttpContext.RequestAborted 和 CancellationToken 参数有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆