我们应该将CancellationToken用于MVC/Web API控制器吗?

use*_*129 41 c# asp.net-mvc async-await asp.net-web-api cancellation-token

异步控制器有不同的示例.其中一些在方法定义中使用CancellationToken:

public async Task<ActionResult> ShowItem(int id, CancellationToken cancellationToken)
{
    await Database.GetItem(id, cancellationToken);
    ...
Run Code Online (Sandbox Code Playgroud)

但是其他示例甚至是VS2013的默认ASP.NET项目根本不使用CancellationToken而没有使用它:

public async Task<ActionResult> ShowItem(int id)
{
    await Database.GetItem(id);
    ...
Run Code Online (Sandbox Code Playgroud)

目前尚不清楚,我们是否应该在控制器中使用CancellationToken(以及为什么).

Ste*_*ary 40

你应该使用它.现在它只适用于你有AsyncTimeout,但很可能未来的MVC/WebAPI版本会将令牌解释为"超时客户端断开连接".

  • 我刚刚在VS 2015下进行了测试,在浏览器中点击停止确实触发了取消令牌. (12认同)

Nid*_*eep 9

用户可以随时通过点击浏览器上的停止或重新加载按钮来取消对您的网络应用程序的请求。通常,您的应用程序无论如何都会继续生成响应,即使 Kestrel 不会将其发送给用户。如果您有一个长时间运行的操作方法,那么您可能需要检测请求何时被取消,并停止执行。

您可以通过将 CancellationToken 注入到操作方法中来完成此操作,该方法将自动绑定到请求的 HttpContext.RequestAborted 令牌。您可以照常检查此令牌是否取消,并将其传递给支持它的任何异步方法。如果请求被取消,则会抛出OperationCanceledException 或TaskCanceledException。

下面的链接详细解释了这种情况。

https://andrewlock.net/using-cancellationtokens-in-asp-net-core-mvc-controllers/


Ram*_*Ram 7

你可以用这个

public async Task<ActionResult> MyReallySlowReport(CancellationToken cancellationToken)
{
    CancellationToken disconnectedToken = Response.ClientDisconnectedToken;
    using (var source = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, disconnectedToken))
    {
        IEnumerable<ReportItem> items;
        using (ApplicationDbContext context = new ApplicationDbContext())
        {
            items = await context.ReportItems.ToArrayAsync(source.Token);
        }
        return View(items);
    }
}
Run Code Online (Sandbox Code Playgroud)

这里带走的。

  • 您必须处置LinkedTokenSource,因为它永远不会被GC收集,并且会导致内存泄漏。MSDN:请注意,完成处理后,必须在链接令牌源上调用Dispose。http://msdn.microsoft.com/en-us/library/dd997364.aspx (2认同)