你如何取消AJAX长时间运行的MVC行动客户端(在JavaScript)?长时间、客户端、行动、AJAX

2023-09-10 13:17:04 作者:太多的情绪没适当的表情

我有一个长期运行的(4-10秒)MVC往返AJAX调用的报告采取行动。虽然它的运行,用户可以更改的参数和运行别的东西,所以我取消使一个又一个前AJAX请求。

I have a long running (4-10 second) MVC action that runs a report from an AJAX call. While it's running users can change the parameters and run something else, so I cancel the AJAX request before making another one.

所以,举例来说(例如jQuery的,但发生问题不分):

So, for instance (example in jQuery but the problem happens regardless):

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

dataRequest = $.ajax(...);

客户端这似乎做工精细,但取消的请求在服务器上仍然运行。举例来说,如果报告需要10秒,并且余抵消并启动其他然后第二请求需要20秒

Client side this appears to work fine, but the cancelled request is still running on the server. For instance if the report takes 10 seconds, and I cancel one and start the other then the second request takes 20 seconds.

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

[如果]两个并发请求在同一会议上提出的(通过使用   相同的SessionID值),第一个请求获取独占访问   会话信息。第二个请求后,才执行   第一请求完成

[If] two concurrent requests are made for the same session (by using the same SessionID value), the first request gets exclusive access to the session information. The second request executes only after the first request is finished.

所以第二请求不能访问会话,直到第一个饰面。使用异步操作的MVC似乎没有解决这个作为动作仍然需要能够进行更改会话

So the second request can't access the session until the first one finishes. Using asynchronous MVC actions doesn't seem to get around this as the action still needs to be able to make changes to the session.

是否有可能阻止一个动作,并开始下不使用 AsyncController [SessionState会(SessionStateBehavior.ReadOnly)]

Is it possible to stop one action and start the next without using AsyncController or [SessionState(SessionStateBehavior.ReadOnly)]?

如果它不是都需要?

推荐答案

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

As it turns out the complete answer required two things:

首先(感谢达林的确认它)会议基本上锁定页面要执行一个接一个。 进一步调查指出这是与ASP.Net会话一个更一般的问题 - 他们只是无法处理乐观并发

Firstly (thanks Darin for confirming it) the session essentially locks the pages to be executed one after the other. Further investigation has pointed to this being a more general problem with ASP.Net sessions - they just can't handle optimistic concurrency.

其次,取消的请求需要检查客户端是否仍然连接。在某些情况下,您可能要继续(如火灾,忘记了ASP的行动),但在这种情况下,如果客户不再等待报告有没有点我们继续对其进行处理。

Secondly the cancelled request needs to check whether the client is still connected. There are situations where you might want to continue (like a fire and forget ASP action) but in this case if the client's no longer waiting for the report there's no point us continuing to process it.

这是作为一个响应的属性: this.Response.IsClientConnected

This is available as a property of the response: this.Response.IsClientConnected

因此​​,为了有效地消除我的服务器端操作时,jQuery的要求它,我不得不写我自己的会话处理程序,并添加定期检查,对 this.Response.IsClientConnected

So to effectively cancel my server side action when jQuery requested it I had to write my own session handler and add regular checks against this.Response.IsClientConnected.