In an ASP.NET Web Forms application I have a parent form, which contains another content page within an IFrame. When user clicks on a link within the content page, a long running process (> 30 min) is started. Upon completion a popup is displayed to the user indicating number of records processed.
I need to prevent session timeout programatically, without changing the default 20 min in Web.config. I have been trying to implement the Heartbeat example posted here (and all over the web, so I know it should work) Keeping ASP.NET Session Open / Alive , but it appears that it's used mostly for idle sessions.
In my case, once the content page request goes to server side and long running process is initiated, the HTTP Handler is not called. When the process completes, all the calls are made immediately one after another like they have been "queued".
Here's my HTTP Handler:
<%@ 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
Javascript function in Head element for parent page. Create interval calling the handler every 8 seconds (to be increased to 10 min in production).
function KeepSessionAlive()
{
if (intervalKeepAliveID)
clearTimeout(intervalKeepAliveID);
intervalKeepAliveID = setInterval(function()
{
$.post("KeepSessionAliveHandler.ashx", null, function()
{
// Empty function
});
}, 8000);
}
intervalKeepAliveID
is declared in a main Javascript file included in all pages of the application.
This is the code for my onclick event in the content page Head
$(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));
});
});
Somewhere I read that Javascript runs in a single thread, but given that fact that my repeating interval is outside the content page, I do not believe this should apply here...