C# 如何处理未打开的会话

C# 如何处理未打开的会话,c#,asp.net-mvc,.net-4.5,asp.net-session,C#,Asp.net Mvc,.net 4.5,Asp.net Session,我正在实现一个会话结构 我在服务器端有一个ConcurrentDictionary,保存所有对 建立新连接时,根据RememberMe选项,将cookie分配给客户端浏览器、perm或temp 当客户端调用注销函数时,它会从字典中删除会话 但是,当客户端浏览器简单地关闭或崩溃,cookie丢失、过期或删除时,内存中的服务器端会话对象将保留在字典中并成为重影。随着时间的推移,这些鬼魂会堆积起来 我的问题是,如何改进设计,以便在失效会话过期后可以清理它们 我想做一个定时服务,运行一个清洁时间表,但它

我正在实现一个会话结构

我在服务器端有一个
ConcurrentDictionary
,保存所有

建立新连接时,根据
RememberMe
选项,将cookie分配给客户端浏览器、perm或temp

当客户端调用
注销
函数时,它会从字典中删除会话

但是,当客户端浏览器简单地关闭或崩溃,cookie丢失、过期或删除时,内存中的服务器端会话对象将保留在字典中并成为重影。随着时间的推移,这些鬼魂会堆积起来

我的问题是,如何改进设计,以便在失效会话过期后可以清理它们


我想做一个定时服务,运行一个清洁时间表,但它感觉不优雅。有没有一种更简单的方法可以做到这一点而不依赖外部服务?

几个月后,我会回答自己的问题。如果我想有一个这样的结构,我会使用微软信号器。因为它以实时方式为我控制会话,而且做得更多。

我的一个项目也有类似的情况

我使用具有较短绝对过期时间和用户会话id的缓存代替字典作为缓存密钥:

HttpContext.Current.Cache.Insert(sessionID, userEntity, null, DateTime.Now.AddSeconds(30), TimeSpan.Zero);
在客户端,我每15秒进行一次ajax调用,通知服务器并为会话id更新缓存

所以,每当用户关闭浏览器窗口时,服务器不会收到任何通知,并且用户的会话id自动过期。

如果您的会话状态为“InProc”,为什么不在会话开始和会话结束时应用您的代码呢

void Session_Start(object sender, EventArgs e)
{
    //Add to ConcurrentDictionary
}

void Session_End(object sender, EventArgs e)
{
    // Note: The Session_End event is raised only when the sessionstate mode
    // is set to InProc in the Web.config file. If session mode is set to StateServer 
    // or SQLServer, the event is not raised.

    //Remove from ConcurrentDictionary
}

最好使用带滚动项的缓存,或者处理Session\u End方法。你们在UserSession中存储了什么?并没有可靠的会话结束方法来处理,若客户端浏览器崩溃,那个么它就在那个里结束了,而并没有和服务器通信。但是现在你提到了缓存,我有了一个主意,我可以存储一个按上次活动时间排序的列表。每当新客户机登录时,他都可以帮助检查队列中最早的会话,并在过期时删除。当每个活动用户调用服务器执行某项操作时,都会将自己排在队列的后面。因此,他成为了最新的活跃人士。您是否需要在某个时候查看登录的每个人的数据?如果没有,为什么不将数据存储在会话中(如果您需要数据),并在会话超时后让它消失呢?如果有压力,也可以通过将项目从会话中删除来处理内存压力。或者使用带有滚动超时的HttpContext.Cache,这样它将在上次访问后的设置时间后消失。(基本上,不需要自己动手。)把问题摆在脑后:根据您对持久性的意图/目标,将持久性转移到客户端是否有效?为什么您仍然使用会话来验证用户。这种方法在ASP时代是一种可行的解决方案,但现在不是了。您应该考虑改用
ASP.NET窗体身份验证
,这是ASP.NET世界中的首选方法。感谢您,按照上述想法进行了一些搜索,在.NET4中实现System.Runtime.Caching似乎是一种可行的方法。