你如何取消AJAX长期运行的MVC动作客户端(在javascript中)?

Kei*_*ith 10 javascript asp.net ajax asp.net-mvc

我有一个长时间运行(4-10秒)的MVC操作,它运行来自AJAX调用的报告.在运行时,用户可以更改参数并运行其他内容,因此我在创建另一个之前取消了AJAX请求.

所以,例如(jQuery中的示例,但无论如何都会出现问题):

// If we have an active request and it's not complete
if(dataRequest && dataRequest.readyState != 'complete') 
{
    dataRequest.abort();
}

dataRequest = $.ajax(...);
Run Code Online (Sandbox Code Playgroud)

客户端这似乎工作正常,但已取消的请求仍在服务器上运行.例如,如果报告需要10秒,我取消一个并启动另一个,那么第二个请求需要20秒.

我认为这是由于会话级锁定:

[If]对同一会话发出两个并发请求(通过使用相同的SessionID值),第一个请求获得对会话信息的独占访问权.第二个请求仅在第一个请求完成后执行.

因此第二个请求在第一个请求完成之前无法访问会话.使用异步MVC操作似乎并没有解决这个问题,因为操作仍然需要能够对会话进行更改.

是否可以停止一个动作并开始下一个动作而不使用AsyncController[SessionState(SessionStateBehavior.ReadOnly)]

如果不是都需要?

Kei*_*ith 4

事实证明,完整的答案需要两件事:

首先(感谢 Darin确认)会话本质上锁定了一个接一个要执行的页面。进一步的调查表明这是 ASP.Net 会话的一个更普遍的问题 - 它们只是无法处理乐观并发。

其次,取消的请求需要检查客户端是否仍然连接。在某些情况下,您可能希望继续(例如“即发即忘”ASP 操作),但在这种情况下,如果客户不再等待报告,我们就没有必要继续处理它。

这可以作为响应的属性使用:this.Response.IsClientConnected

因此,为了在 jQuery 请求时有效地取消我的服务器端操作,我必须编写自己的会话处理程序并添加针对this.Response.IsClientConnected.