在 ASP.NET Web 窗体应用程序中,我有一个父窗体,它在 IFrame 中包含另一个内容页面。当用户单击内容页面中的链接时,将启动一个长时间运行的过程(> 30 分钟)。完成后,会向用户显示一个弹出窗口,指示已处理的记录数。
我需要以编程方式防止会话超时,而不更改 Web.config 中的默认 20 分钟。我一直在尝试实现此处发布的 Heartbeat 示例(以及整个网络,所以我知道它应该可以工作) Keeping ASP.NET Session Open / Alive ,但它似乎主要用于空闲会话。
就我而言,一旦内容页面请求进入服务器端并启动长时间运行的进程,就不会调用 HTTP 处理程序。当这个过程完成时,所有的调用都会像被“排队”一样立即一个接一个地进行。
这是我的 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
父页面的 Head 元素中的 Javascript 函数。创建间隔每 8 秒调用一次处理程序(在生产中增加到 10 分钟)。
function KeepSessionAlive()
{
if (intervalKeepAliveID)
clearTimeout(intervalKeepAliveID);
intervalKeepAliveID = setInterval(function()
{
$.post("KeepSessionAliveHandler.ashx", null, function()
{
// Empty function
});
}, 8000);
}
intervalKeepAliveID
在应用程序所有页面中包含的主要 Javascript 文件中声明。
这是我在内容页面 Head 中的 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 在单个线程中运行,但鉴于我的重复间隔在内容页面之外,我认为这不应该适用于此......