我的目的是确保在应用程序池停止或重新启动时,所有登录的用户都不会注销。
一种方法是,我可以用完代理会话并将其直接存储在数据库中,但这会影响应用程序的性能,所以我不想这样做。
我发现的另一种方法是,我可以在托管环境中注册一个“ 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文件的会话开始和会话结束事件?这会影响内存利用率吗?
答案 0 :(得分:0)
我做了进一步调查,并创建了一个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;
}
}