【问题标题】:Abort AJAX request via CancellationToken in ASP.NET MVC在 ASP.NET MVC 中通过 CancellationToken 中止 AJAX 请求
【发布时间】:2018-11-09 21:31:27
【问题描述】:

我有一个与外部资源交互的 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();
});

如果我正确理解了这个article,取消令牌通过框架模型绑定器与请求绑定,无需对其进行任何操作。当用户关闭模态表单时,在浏览器 concole 中我可以看到请求的状态为“已取消”,但在服务器端的慢速操作仍在执行。我也试过

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

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

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

【问题讨论】:

    标签: c# asp.net-mvc task-parallel-library asp.net-ajax cancellation


    【解决方案1】:

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

    Using CancellationToken for timeout in Task.Run does not work

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

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

    【讨论】:

      猜你喜欢
      • 2015-08-22
      • 2017-10-30
      • 2021-09-08
      • 2018-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多