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

Решение в основном вставляет элемент в кеш при входе пользователей в систему, а затем обновляет кеш при каждом запросе. Наконец, он использует событие истечения срока действия кэша, чтобы определить, когда истек срок сеанса.

Другие вопросы по тегам