HttpContext.Current.Session является нулевым для синхронизированного события
Я разработал систему электронной коммерции на основе ASP.NET и ERP-системы Microsoft Dynamics AX 4.0.
Для каждого HTTP-сеанса я подключаюсь к системе ERP с помощью "Бизнес-коннектора", компонента.NET. Объект бизнес-коннектора хранится в переменной сеанса. Поэтому при обычном Session_end я выйду из Dynamics AX и вычистлю все ресурсы
Система ERP представляет собой 32-разрядную систему, и для экономии ресурсов я хотел бы разработать таймер, который выходит из системы ERP после определенного времени бездействия. Скажем 2 минуты. Время ожидания сеанса Http устанавливается на 20 минут.
Я сделал класс "TimerHandler", который использует System.Timers.Timer
, который запускает и перезапускает таймер каждый раз, когда пользователь нажимает на что-то, связанное с системой ERP (товары, корзина и т. д.).
Пример кода:
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;
}
}
Этот код никогда не выйдет из системы OnTimedEvent
, как HttpContext.Current.Session
нулевой.
Насколько я понимаю, таймер работает в другом потоке, поэтому текущий сеанс недоступен, когда мне это нужно.
Так как же я могу "добраться" до этой нити? Или я могу убедиться, что таймер работает в том же потоке, что и сеанс?
1 ответ
HttpContext.Current
действительно только в течение срока действия запроса. Когда ваш таймер срабатывает, запрос, вероятно, уже давно обработан и завершен.
Если вы хотите обработать некоторые данные для конкретного пользователя, вам, вероятно, следует скопировать информацию из словаря сеансов в своего рода держатель данных.
Вот решение, которое использует встроенный кэш для определения истечения времени сессий: http://www.ivan-nikolov.com/en/article/5/asp-net-session-state-mode-and-session-end-callback
Решение в основном вставляет элемент в кеш при входе пользователей в систему, а затем обновляет кеш при каждом запросе. Наконец, он использует событие истечения срока действия кэша, чтобы определить, когда истек срок сеанса.