如何取消AJAX长期运行的MVC操作客户端(javascript)?
我有一个长时间运行(4-10秒)的MVC操作,它运行来自AJAX调用的报告。当它运行时,用户可以更改参数并运行其他内容,因此我在发出另一个AJAX请求之前取消了AJAX请求 因此,例如(例如在jQuery中,但无论如何问题都会发生): 客户端这似乎工作正常,但已取消的请求仍在服务器上运行。例如,如果报告需要10秒,我取消一个并启动另一个,那么第二个请求需要20秒 我认为这是由于: [如果]针对同一会话发出两个并发请求(通过使用 相同的SessionID值),第一个请求以独占方式访问 会话信息。第二个请求仅在 第一个请求完成了 因此,在第一个请求完成之前,第二个请求无法访问会话。使用异步MVC操作似乎无法解决这一问题,因为该操作仍然需要能够对会话进行更改 是否可以停止一个操作并启动下一个操作,而不使用如何取消AJAX长期运行的MVC操作客户端(javascript)?,javascript,asp.net,ajax,asp.net-mvc,Javascript,Asp.net,Ajax,Asp.net Mvc,我有一个长时间运行(4-10秒)的MVC操作,它运行来自AJAX调用的报告。当它运行时,用户可以更改参数并运行其他内容,因此我在发出另一个AJAX请求之前取消了AJAX请求 因此,例如(例如在jQuery中,但无论如何问题都会发生): 客户端这似乎工作正常,但已取消的请求仍在服务器上运行。例如,如果报告需要10秒,我取消一个并启动另一个,那么第二个请求需要20秒 我认为这是由于: [如果]针对同一会话发出两个并发请求(通过使用 相同的SessionID值),第一个请求以独占方式访问 会话信息。第
AsyncController
或[SessionState(SessionStateBehavior.ReadOnly)]
如果不是,则两者都是必需的?[SessionState(SessionStateBehavior.ReadOnly)]
或完全禁用会话足以允许从同一会话并发访问控制器操作。因此,第二个请求(来自同一会话)不需要等待第一个请求完成后再进行处理。就取消服务器上的第一个操作而言,这将更加困难。您必须将每个任务关联到一个唯一的id,并在启动新任务时将此任务id返回给客户端。然后,当您通过调用.abort()
取消客户端上的AJAX请求时,您可以向其他控制器操作发出另一个AJAX请求,并将唯一的任务id传递给它。此控制器操作本身将设置一些公共标志,以指示要停止的第一个操作
具有内置的取消支持,您可以查看以简化该功能,以避免2之间的共享数据结构将它们同步。因为完整的答案需要两件事: 首先(感谢Darin),会话本质上锁定了一个接一个执行的页面。已经指出这是ASP.Net会话的一个更普遍的问题——它们无法处理乐观并发 其次,取消的请求需要检查客户端是否仍然连接。在某些情况下,您可能希望继续执行(如fire and forget ASP操作),但在这种情况下,如果客户不再等待报告,我们就没有必要继续处理它 这可以通过以下方式获得:
This.Response.IsClientConnected
因此,为了在jQuery请求时有效地取消服务器端操作,我必须编写自己的会话处理程序,并针对
this.Response.IsClientConnected
。abort()只是客户端取消。如果您想在服务器端监视它,一个好方法是轮询IsClientConnected属性,它将告诉您ajax通信的状态 我已经在使用TPL来做很多需要花费时间的工作——我正在以大约4-10秒的并行速度执行大约25秒的长时间连续运行的代码。然而,使用它来处理中止看起来确实像是重新发明轮子;当新请求已经被取消时,为什么新请求需要告诉旧请求(仍在运行)中止?@Keith,告诉旧请求中止的不是新请求。您必须发送一个新的特殊AJAX请求,通知服务器中止对特定任务的处理。当您执行dataRequest.abort()时代码>您只是在中止AJAX请求,但是如果您想中止服务器端处理,您需要做更多的工作。嗯,所以IIS不知道该请求已在传输级别被取消?当等待的连接在传输级别终止时,我希望页面线程在IIS/ASP级别中止。IIS确实如此-我需要做的只是在长时间运行的页面中检查响应。IsClientConnected
。当该属性变为false时,我将取消我正在执行的操作。请小心依赖IsClientConnected
,因为检查它显然会导致严重的性能问题,请参见Hi Keith!我有一个类似的问题,但即使有你的答案也无法解决,()有什么办法帮我吗?或者您可以发布一个示例代码来触发this.Response.IsClientConnected
查看接受的答案和原始问题。这个答案没有添加任何尚未声明的内容。使用IsClientConnected
时也要格外小心,因为检查它显然会带来严重的性能问题,请参见(显然,检查它可能需要花费½s的时间,但没有人能够确认)您是对的,我已经阅读了您的帖子,我必须修改我的解决方案。
// If we have an active request and it's not complete
if(dataRequest && dataRequest.readyState != 'complete')
{
dataRequest.abort();
}
dataRequest = $.ajax(...);