I have developed an e-commerce system based on ASP.NET and an ERP system, Microsoft Dynamics AX 4.0.
For each HTTP session, I logon to the ERP system using a "Business connector", a .NET component. The "Business connector"-object is stored in a session-variable. So at a normal Session_end, I will log out from Dynamics AX and clean up all resources
The ERP system is a 32-bit based system, and to save resources I would like to develop a timer that logs out of the ERP-system after a certain time of inactivity. Lets say 2 minutes. The Http session timeout is set for 20 minutes.
I made a class, "TimerHandler" that uses System.Timers.Timer
, that starts and restarts the timer every time the user click on something related to the ERP system (items, basket etc).
Example code:
public class ErpHandler
{
private ErpTimerHandler TimerHandler
{
get
{
if (HttpContext.Current != null)
{
if (HttpContext.Current.Session["TimerHandler"] != null)
{
return (ErpTimerHandler)HttpContext.Current.Session["TimerHandler"];
}
}
return null;
}
set
{
if (HttpContext.Current != null)
{
HttpContext.Current.Session["TimerHandler"] = value;
}
}
}
private void StartTimer()
{
ErpTimerHandler timer = TimerHandler;
if timer == null)
{
timer = TimerHandler.Instance();
timer.TimerEvent += OnTimedEvent;
TimerHandler = timer;
}
timer.StartTimer();
}
private void StopTimer()
{
ErpTimerHandler timer = TimerHandler;
if (timer != null)
{
timer.StopTimer();
TimerHandler = null;
}
}
private void OnTimedEvent(Object source, EventArgs e)
{
StopTimer();
ErpLogOff();
}
public void ErpLogOff()
{
ErpSystem erp = ErpInstance;
if (LoggedOnErp && erp != null)
{
erp.Logoff();
ErpInstance = null;
}
LoggedOnErp = false;
}
}
This code will never log off the Erp on OnTimedEvent
, as HttpContext.Current.Session
is null.
From what I understand, the timer is running on a different thread, hence the current session is not available when I need it.
So how on earth can I "reach" that thread? Or can i make sure the timer run on the same thread as the session?
HttpContext.Current
is only valid during the request lifetime. When your timer triggers the request have probably since long been processed and completed.If you want to process some data for a specific user you should probably copy the information from the session dictionary into a sort of data holder.
Here is a solution which uses the built in cache to detect when sessions expire: http://www.ivan-nikolov.com/en/article/5/asp-net-session-state-mode-and-session-end-callback
The solution basically inserts an item into the cache when the users logs in, and then updates the cache on every request. Finally it uses the cache expire event to detect when a session have expired.