Javascript 使用jQuery为长时间运行的进程保持会话活动
在ASP.NET Web窗体应用程序中,我有一个父窗体,它在IFrame中包含另一个内容页。当用户单击内容页内的链接时,将启动一个长时间运行的过程(>30分钟)。完成后,将向用户显示一个弹出窗口,指示处理的记录数 我需要通过编程防止会话超时,而不更改Web.config中的默认20分钟。 我一直在尝试实现这里发布的Heartbeat示例(以及整个web,所以我知道它应该可以工作) ,但它似乎主要用于空闲会话 在我的例子中,一旦内容页请求转到服务器端并启动长时间运行的进程,就不会调用HTTP处理程序。当流程完成时,所有调用都会像“排队”一样一个接一个地进行 下面是我的HTTP处理程序:Javascript 使用jQuery为长时间运行的进程保持会话活动,javascript,jquery,asp.net,Javascript,Jquery,Asp.net,在ASP.NET Web窗体应用程序中,我有一个父窗体,它在IFrame中包含另一个内容页。当用户单击内容页内的链接时,将启动一个长时间运行的过程(>30分钟)。完成后,将向用户显示一个弹出窗口,指示处理的记录数 我需要通过编程防止会话超时,而不更改Web.config中的默认20分钟。 我一直在尝试实现这里发布的Heartbeat示例(以及整个web,所以我知道它应该可以工作) ,但它似乎主要用于空闲会话 在我的例子中,一旦内容页请求转到服务器端并启动长时间运行的进程,就不会调用HTTP处理程
<%@ WebHandler Language="VB" Class="KeepSessionAliveHandler" %>
Imports System
Imports System.Web
Public Class KeepSessionAliveHandler
Implements IHttpHandler, SessionState.IRequiresSessionState
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
context.Session("heartbeat") = DateTime.Now
context.Response.AddHeader("Content-Length", "0")
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
intervalKeepAliveID
在应用程序所有页面中包含的主Javascript文件中声明
这是内容页标题中onclick事件的代码
$(document).ready(function()
{
// Ensuring my code is executed before ASP.NET generated script
$("#oGroup_lnkSubmit_lnkButton").attr("onclick", null).removeAttr("onclick").click(function()
{
// Prevent the browser from running away
// e.preventDefault();
window.parent.KeepSessionAlive();
// Wave goodbye
//window.location.href = $(this).attr('href');
WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions($(this).attr("name"), "", true, "", "", false, false));
});
});
我在某个地方读到Javascript在一个线程中运行,但鉴于我的重复间隔在内容页之外,我认为这不应该适用于这里…JS是单线程的问题-AJAX的a代表异步-例如它不阻塞(即使您让它阻塞,它实际上只是在收到响应之前保持状态) 从这个 每个会话对ASP.NET会话状态的访问是独占的,这意味着如果两个不同的用户同时发出请求,则会同时授予对每个单独会话的访问权限。但是,如果对同一会话发出两个并发请求(使用相同的SessionID值),第一个请求以独占方式访问会话信息。第二个请求仅在第一个请求完成后执行。(如果由于第一个请求超过锁定超时而释放了对信息的独占锁定,则第二个会话也可以访问。)如果@Page指令中的EnableSessionState值设置为ReadOnly,则对只读会话信息的请求不会导致对会话数据的独占锁定。但是,对会话数据的只读请求可能仍必须等待由对会话数据的读写请求设置的锁定清除
有关该问题的更详细解释和解决方法,您可以更好地控制阻塞的实现方式和潜在的解决方法。我认为这里有两个移动部件相互阻塞,无法正常工作
- 因为您的进程正在服务器线程中运行,所以这会阻止处理其他请求
- 因为keepalive依赖于从服务器获取响应,所以它不会完成
我建议您研究一种解决方案,例如,将长时间运行的进程作为一个单独的线程生成,以便您的服务器可以继续为传入的请求提供服务。您使用什么来响应用户?(您的页面是否轮询完成?还是使用服务器端信号框架?)而且,长时间运行的进程是否直接在服务器线程中运行?或者是否启动了工作线程?导致访问会话的请求被阻止,而另一个请求可能具有对会话的写访问权限。这是为了防止cropss线程问题。我在其他地方的回答中给出了详细信息,我将看看是否可以找到它。没有工作线程线程,它是onclick事件背后代码的一部分(它实际上是一个使用链接的用户控件)。我可以在Firebug调试器中看到我的代码被命中。该页面不轮询是否完成。它是相当标准的Web表单-“单击执行长时间运行的进程并返回;还显示弹出窗口”正确!感谢您花时间理解我的长问题,感谢您快速的回答。@Chicagomykindtown非常欢迎您-我认识到了这个问题,因为我自己以前也遇到过。欢迎访问SO。希望我们将来能见到您。感谢您花时间理解我的长问题并提供答案!
$(document).ready(function()
{
// Ensuring my code is executed before ASP.NET generated script
$("#oGroup_lnkSubmit_lnkButton").attr("onclick", null).removeAttr("onclick").click(function()
{
// Prevent the browser from running away
// e.preventDefault();
window.parent.KeepSessionAlive();
// Wave goodbye
//window.location.href = $(this).attr('href');
WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions($(this).attr("name"), "", true, "", "", false, false));
});
});