【问题标题】:How to get all active session from asp.net application如何从 asp.net 应用程序获取所有活动会话
【发布时间】:2019-06-11 11:02:54
【问题描述】:

我的目的是确保在应用程序池停止或重新启动时所有登录的用户都不会被注销。

一种方法是我可以使用代理会话并将它们直接存储在数据库中,但这会影响应用程序性能,所以我不想这样做。

我发现的另一种方法是,我可以在托管环境中注册一个“IRegisteredObject”实现的类对象。

public class SessionTracker : IRegisteredObject
{
        //I created this class as singleton and exposed GetInstance method
        public void Stop(bool immediate)
        {
            //Here i want to get all the sessions and store them in database
        }

}

在全局对象中注册

public class Global : System.Web.HttpApplication
{

        protected void Application_Start(Object sender, EventArgs e)
        {
             HostingEnvironment.RegisterObject(SessionTracker.GetInstance());

        }
}

我想获取应用程序的所有活动会话,以便在应用程序池重新启动或突然停止时将它们存储在数据库中。

现在当我的应用程序启动时,那时我将再次加载所有数据库存储的会话状态,并且所有会话状态都将有效。

我还发现我可以使用会话开始和会话结束事件并在列表对象中添加会话。我不确定它的效率有多高,因为它会在服务器端占用更多内存。

请提出一种方法,让我可以一次获得所有会话。或者如果我使用 global.ascx.cs 文件的会话开始和会话结束事件可以吗?会影响内存利用率吗?

【问题讨论】:

  • One way is that i can use out prox sessions and directly store them in database but this is going to impact application performance so i dont want to do that. 那是你应该做的。
  • 谢谢@mjwills,你认为它会增加内存利用率吗?
  • @mjwills 我测试了它并且所有会话都引用了同一个对象。所以没有内存问题

标签: c# asp.net session iis


【解决方案1】:

我做了进一步的调查并创建了一个 POC 来检查它是按引用还是按值创建 Sessions 的副本。

我发现它通过引用创建副本。所以从技术上讲,如果我在 SessionTracker 类中添加它们的引用,就没有内存使用问题。如果有人有兴趣了解它,这里是 SessionTracker 类的完整实现

public class SessionTracker : IRegisteredObject
{
    static readonly SessionTracker Tracker = new SessionTracker();
    private static readonly Dictionary<string, HttpSessionState> _sessions = new Dictionary<string, HttpSessionState>();
    private static readonly object padlock = new object();
    private SessionTracker()
    {
    }
    public void Stop(bool immediate)
    {
        try
        {
            //store them in database
        }
        catch (Exception ex)
        {
            throw;
        }
    }

    public void AddSession(HttpSessionState session)
    {
        lock (padlock)
        {
            _sessions.Add(session.SessionID, session);
        }
    }

    public void RemoveSession(HttpSessionState session)
    {
        lock (padlock)
        {
            _sessions.Remove(session.SessionID);
        }
    }

    public static SessionTracker GetInstance()
    {
        return Tracker;
    }


}

【讨论】:

  • 考虑将_sessions 设为ConcurrentDictionary 以消除对lock 的需求。
猜你喜欢
  • 2012-02-09
  • 2019-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-10
  • 1970-01-01
  • 2010-12-01
相关资源
最近更新 更多