【问题标题】:HttpContext.Current.Session is null on timed eventHttpContext.Current.Session 在定时事件上为空
【发布时间】:2014-05-26 13:37:27
【问题描述】:

我已经开发了一个基于 ASP.NET 的电子商务系统和一个 ERP 系统,Microsoft Dynamics AX 4.0。

对于每个 HTTP 会话,我使用 “业务连接器”(一个 .NET 组件)登录到 ERP 系统。 “业务连接器”-对象存储在 会话变量 中。所以在正常的Session_end,我将从 Dynamics AX 中注销并清理所有资源

ERP 系统是一个基于 32 位的系统,为了节省资源,我想开发一个计时器,在一段时间不活动后退出 ERP 系统。让我们说2分钟。 Http 会话超时 设置为 20 分钟。

我创建了一个使用System.Timers.Timer 的类“TimerHandler”,每次用户单击与 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 上注销 Erp,因为 HttpContext.Current.Session 为空。

据我了解,计时器在不同的线程上运行,因此当前会话在我需要时不可用。

那么我到底如何才能“到达”那个线程呢?或者我可以确保计时器与会话在同一线程上运行吗?

【问题讨论】:

    标签: asp.net timer session-variables axapta business-connector


    【解决方案1】:

    HttpContext.Current 仅在请求生命周期内有效。当您的计时器触发请求时,可能早就处理并完成了。

    如果您想为特定用户处理某些数据,您可能应该将会话字典中的信息复制到某种数据持有者中。

    这是一个使用内置缓存来检测会话何时过期的解决方案:http://www.ivan-nikolov.com/en/article/5/asp-net-session-state-mode-and-session-end-callback

    该解决方案基本上是在用户登录时将一个项目插入缓存,然后在每次请求时更新缓存。最后,它使用缓存过期事件来检测会话何时过期。

    【讨论】:

    • 即使HttpContext.Current 无效,会话仍然存在于服务器上,所以应该可以通过某种方式访问​​它吗?在下一次请求时,会话再次可用。我认为我无法将我的 Business Connector 存储在缓存中,但我会调查一下。
    • 不是没有HttpContext。这是文档:msdn.microsoft.com/en-us/library/vstudio/…
    猜你喜欢
    • 2010-09-18
    • 2012-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 2015-09-21
    相关资源
    最近更新 更多