繁体   English   中英

通过ASP.NET MVC中的CancellationToken中止AJAX请求

[英]Abort AJAX request via CancellationToken in ASP.NET MVC

我有一个与外部资源交互的ASP.NET MVC应用程序,并且有一个操作需要花费很多时间。 所以在控制器中我有这样的方法

[HttpPost]
public async Task<JsonResult> SomeMethod(..., CancellationToken token)
{
    await _someService.ExecuteSlowOperationAsync(..., token);
    ...
}

而这种缓慢的操作看起来像

public async Task ExecuteSlowOperationAsync(..., CancellationToken token)
{
    return await Task.Run(() => 
    {
       //interacting with external resource
    }, token);
} 

此方法与模态视图链接,如果请求将花费这么多时间用户可能决定关闭它。 根据我必须取消请求而不等待结果,所以在客户端我有代码就好

...
var request = $.ajax(...);

...

$('#modal').on('hidden.bs.modal', function () {
  request.abort();
});

如果我正确地理解了这篇文章 ,取消令牌会通过框架模型绑定器与请求绑定,而不需要对它做任何事情。 当用户关闭模态窗体时,在浏览器中我可以看到请求获取状态“已取消”但在服务器端缓慢操作仍在执行。 我试过了

CancellationToken disconnectedToken = Response.ClientDisconnectedToken;            
var source = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, disconnectedToken);

然后从这个来源获取令牌,但仍然一无所获。

我觉得我错过了一些重要的事情并对这种情况产生了误解。 任何想法如何使其工作?

我的回答可能有点晚了。 但我想我找到了你的问题。 使用Task.Run(Action action, CancellationToken cancellationToken)取消长时间运行的操作可能并不总是有效。

在Task.Run中使用CancellationToken超时不起作用

如果长时间运行的操作在你自己的代码中,你应该写这样的东西

public async Task ExecuteSlowOperationAsync(..., CancellationToken token)
{
    while (true)
    {
        if(cancelToken.IsCancellationRequested)
        {
            return;
        }
        ...
    }
}

如果您无法修改长时间运行操作本身的源代码,可以使用Microsoft.VisualStudio.Threading.ThreadingTools中的 WithCancellation (有关详细信息,请参阅https://stackoverflow.com/a/33396646/9483821 ),您甚至可以使用它早些时候你的控制器

[HttpPost]
public async Task<JsonResult> SomeMethod(..., CancellationToken token)
{
     CancellationToken disconnectedToken = Response.ClientDisconnectedToken;            
     var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, disconnectedToken).Token;
     await _someService.ExecuteSlowOperationAsync(...).WithCancellation(linkedToken);
     ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM