Session.Abandon和Session.Clear的实现和区别
我在网上找了一个比较贴切的描述:
Session.Clear()就是把Session对象中的所有项目都删除了,Session对象里面啥都没有。但是Session对象还保留。Session.Abandon()就是把当前Session对象删除了,下一次就是新的Session了。(下一次新会话开始貌似并不会产生新的SESSIONID)主要的不同之处在于当使用Session.Abandon时,会调用Session_End方法(InProc模式下)。当下一个请求到来时将激发Session_Start方法。而Session.Clear只是清除Session中的所有数据并不会中止该Session,因此也不会调用那些方法。其中标红也不是很正确。
首先我们来看一下code:
Dictionary<string, HttpSessionState> dict = new Dictionary<string, HttpSessionState>();
// Abandon
dict.Remove(key);
//Clear()
dict[key].Clear();
假设session存储一个字典结构,key就是我们客户端的sessionID,value 就是我们的SessionSate(它也是一个集合),调用Abandon后就把key删除了,但是clear是value里面的内容清空了。这2个方法的实现大家可以参考HttpSessionStateContainer的实现,Clear 清空集合,Abandon设置变量使其属性IsAbandoned为true。
真正的核心code在SessionStateModule类的OnReleaseState方法里面,在有Session的Http请求中,有一个地方加载我们的session,也有一个地方保存我们的session。
/// <devdoc>/// <para>[To be supplied.]</para>/// </devdoc>void OnReleaseState(Object source, EventArgs eventArgs) {HttpApplication app;HttpContext context;bool setItemCalled = false;Debug.Trace("SessionStateOnReleaseState", "Beginning SessionStateModule::OnReleaseState");Debug.Assert(!(_rqAddedCookie && !_rqIsNewSession),"If session id was added to the cookie, it must be a new session.");// !!!// Please note that due to InProc session id optimization, this function should not// use _rqId directly because it can still be null. Instead, use DelayedGetSessionId(). _releaseCalled = true;app = (HttpApplication)source;context = app.Context;ChangeImpersonation(context, false);try {if (_rqSessionState != null) {bool delayedSessionState = (_rqSessionState == s_delayedSessionState);Debug.Trace("SessionStateOnReleaseState", "Remove session state from context");SessionStateUtility.RemoveHttpSessionStateFromContext(_rqContext, delayedSessionState);/** Don't store untouched new sessions.*/if (// The store doesn't have the session state.// ( Please note we aren't checking _rqIsNewSession because _rqIsNewSession// is lalso true if the item is converted from temp to perm in a GetItemXXX() call.) _rqSessionStateNotFound// OnStart is not defined&& _sessionStartEventHandler == null// Nothing has been stored in session state&& (delayedSessionState || !_rqSessionItems.Dirty)&& (delayedSessionState || _rqStaticObjects == null || _rqStaticObjects.NeverAccessed)) {Debug.Trace("SessionStateOnReleaseState", "Not storing unused new session.");}else if (_rqSessionState.IsAbandoned) {Debug.Trace("SessionStateOnReleaseState", "Removing session due to abandonment, SessionId=" + _rqId);if (_rqSessionStateNotFound) {// The store provider doesn't have it, and so we don't need to remove it from the store.// However, if the store provider supports session expiry, and we have a Session_End in global.asax,// we need to explicitly call Session_End.if (_supportSessionExpiry) {if (delayedSessionState) {Debug.Assert(s_allowDelayedStateStoreItemCreation, "s_allowDelayedStateStoreItemCreation");Debug.Assert(_rqItem == null, "_rqItem == null");InitStateStoreItem(false /*addToContext*/);}_onEndTarget.RaiseSessionOnEnd(ReleaseStateGetSessionID(), _rqItem);}}else {Debug.Assert(_rqItem != null, "_rqItem cannot null if it's not a new session");// Remove it from the store because the session is abandoned. _store.RemoveItem(_rqContext, ReleaseStateGetSessionID(), _rqLockId, _rqItem);}}else if (!_rqReadonly ||(_rqReadonly &&_rqIsNewSession &&_sessionStartEventHandler != null &&!SessionIDManagerUseCookieless)) {// We need to save it since it isn't read-only// See Dev10 588711: Issuing a redirect from inside of Session_Start event // triggers an infinite loop when using pages with read-only session state// We save it only if there is no error, and if something has changed (unless it's a new session)if ( context.Error == null // no error&& ( _rqSessionStateNotFound|| _rqSessionItems.Dirty // SessionItems has changed.|| (_rqStaticObjects != null && !_rqStaticObjects.NeverAccessed) // Static objects have been accessed|| _rqItem.Timeout != _rqSessionState.Timeout // Timeout value has changed )) {if (delayedSessionState) {Debug.Assert(_rqIsNewSession, "Saving a session and delayedSessionState is true: _rqIsNewSession must be true");Debug.Assert(s_allowDelayedStateStoreItemCreation, "Saving a session and delayedSessionState is true: s_allowDelayedStateStoreItemCreation");Debug.Assert(_rqItem == null, "Saving a session and delayedSessionState is true: _rqItem == null");InitStateStoreItem(false /*addToContext*/);}#if DBGif (_rqSessionItems.Dirty) {Debug.Trace("SessionStateOnReleaseState", "Setting new session due to dirty SessionItems, SessionId=" + _rqId);}else if (_rqStaticObjects != null && !_rqStaticObjects.NeverAccessed) {Debug.Trace("SessionStateOnReleaseState", "Setting new session due to accessed Static Objects, SessionId=" + _rqId);}else if (_rqSessionStateNotFound) {Debug.Trace("SessionStateOnReleaseState", "Setting new session because it's not found, SessionId=" + _rqId);}else {Debug.Trace("SessionStateOnReleaseState", "Setting new session due to options change, SessionId=" + _rqId +"\n\t_rq.timeout=" + _rqItem.Timeout.ToString(CultureInfo.InvariantCulture) +", _rqSessionState.timeout=" + _rqSessionState.Timeout.ToString(CultureInfo.InvariantCulture));} #endifif (_rqItem.Timeout != _rqSessionState.Timeout) {_rqItem.Timeout = _rqSessionState.Timeout;}s_sessionEverSet = true;setItemCalled = true;_store.SetAndReleaseItemExclusive(_rqContext, ReleaseStateGetSessionID(), _rqItem, _rqLockId, _rqSessionStateNotFound);}else {// Can't save it because of various reason. Just release our exclusive lock on it.Debug.Trace("SessionStateOnReleaseState", "Release exclusive lock on session, SessionId=" + _rqId);if (!_rqSessionStateNotFound) {Debug.Assert(_rqItem != null, "_rqItem cannot null if it's not a new session");_store.ReleaseItemExclusive(_rqContext, ReleaseStateGetSessionID(), _rqLockId);}}} #if DBGelse {Debug.Trace("SessionStateOnReleaseState", "Session is read-only, ignoring SessionId=" + _rqId);} #endifDebug.Trace("SessionStateOnReleaseState", "Returning from SessionStateModule::OnReleaseState");}if (_rqAddedCookie && !setItemCalled && context.Response.IsBuffered()) {_idManager.RemoveSessionID(_rqContext);}}finally {RestoreImpersonation();}// WOS 1679798: PERF: Session State Module should disable EndRequest on successful cleanupbool implementsIRequiresSessionState = context.RequiresSessionState;if (HttpRuntime.UseIntegratedPipeline && (context.NotificationContext.CurrentNotification == RequestNotification.ReleaseRequestState) && (s_canSkipEndRequestCall || !implementsIRequiresSessionState)) {context.DisableNotifications(RequestNotification.EndRequest, 0 /*postNotifications*/);_acquireCalled = false;_releaseCalled = false;ResetPerRequestFields();}}
其中主要的code是:
else if (_rqSessionState.IsAbandoned) {Debug.Trace("SessionStateOnReleaseState", "Removing session due to abandonment, SessionId=" + _rqId);if (_rqSessionStateNotFound) {// The store provider doesn't have it, and so we don't need to remove it from the store.// However, if the store provider supports session expiry, and we have a Session_End in global.asax,// we need to explicitly call Session_End.if (_supportSessionExpiry) {if (delayedSessionState) {Debug.Assert(s_allowDelayedStateStoreItemCreation, "s_allowDelayedStateStoreItemCreation");Debug.Assert(_rqItem == null, "_rqItem == null");InitStateStoreItem(false /*addToContext*/);}_onEndTarget.RaiseSessionOnEnd(ReleaseStateGetSessionID(), _rqItem);}}else {Debug.Assert(_rqItem != null, "_rqItem cannot null if it's not a new session");// Remove it from the store because the session is abandoned. _store.RemoveItem(_rqContext, ReleaseStateGetSessionID(), _rqLockId, _rqItem);}}
if (_rqAddedCookie && !setItemCalled && context.Response.IsBuffered()) {
_idManager.RemoveSessionID(_rqContext);
}
_rqAddedCookie 一般情况下为false,所以SessionID 默认也就没有被移除。也就是调用Abandon方法默认Session ID是不会改变的。 _onEndTarget.RaiseSessionOnEnd(ReleaseStateGetSessionID(), _rqItem);就是调用我们的Session_End方法。看到这里大家应该知道什么情况调用Session_End,什么有调用 _store.RemoveItem(_rqContext, ReleaseStateGetSessionID(), _rqLockId, _rqItem); 还有后面 _store.SetAndReleaseItemExclusive(_rqContext, ReleaseStateGetSessionID(), _rqItem, _rqLockId, _rqSessionStateNotFound);这个方法也很重要哦, 就是保存我们的Session大家可以参考 asp.net mvc Session RedisSessionStateProvider锁的实现
Session.Abandon和Session.Clear的实现和区别相关推荐
- Session.Abandon和Session.Clear有何不同
Session.Clear()就是把Session对象中的所有项目都删除了, Session对象里面啥都没有.但是Session对象还保留. Session.Abandon()就是把当前Session ...
- Session.Abandon和Session.Clear有何不同?
主要的不同之处在于当使用Session.Abandon时,会调用Session_End方法(InProc模式下).当下一个请求到来时将激发Session_Start方法.而Session.Clear只 ...
- 11_Flask之Session 设置session有效期 获取session 删除session
文章目录 1 什么是session? 2 实现session的两种思路 3 如何在flask中实现session? 3.1 设置session 3.2 设置session有效期 3.3 获取sessi ...
- Cookie、session和localStorage、以及sessionStorage之间的区别
转载自https://www.cnblogs.com/zr123/p/8086525.html Cookie.session和localStorage.以及sessionStorage之间的区别 一. ...
- session传递参数_分布式 Session 之 Spring Session 架构与设计
作者 | 李增光 杏仁后端工程师.「只有变秃,才能变强!」 前言 开始进行 Web 开发时,我们可能会遇到这样的情况,当服务器重启之后,之前的登录状态会失效需要重新登录.又或者你的应用程序部署了不止 ...
- Session分布式共享 = Session + Redis + Nginx
一.Session 1.Session 介绍 我相信,搞Web开发的对Session一定再熟悉不过了,所以我就简单的介绍一下. Session:在计算机中,尤其是在网络应用中,称为"会话控制 ...
- php session 域,PHP session 跨子域问题总结
今天,做项目时候遇到个问题.之前做东西的时候session一般就直接存在数据库中这样就能解决跨域 不仅仅是跨子域,但是今天遇到这个问题是,自己要在别人现有的东西上面做修改.由于仅仅是子域 当时就行肯定 ...
- session、flask session知识的相关收集
1.打开两个浏览器窗口访问应用程序会使用同一个session还是不同的session session cookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的ses ...
- 利用spring session解决共享Session问题
https://blog.csdn.net/patrickyoung6625/article/details/45694157 1.共享Session问题 HttpSession是通过Servlet容 ...
最新文章
- aes前台加密后台解密
- 敲黑板了!网络推广软件教你如何有效提高网站权重?
- Zookeeper分布式一致性原理(九):Zookeeper分布式应用
- [转载]漫谈游戏中的阴影技术
- SAP Spartacus pageSlot一览
- 数据结构---prim最小生成树
- python - 输出最大/最小的 k 个元素的索引
- DeOccNet:国防科大提出阵列相机去除前景遮挡成像新方法
- 浅析类的const成员函数,类的const对象
- zabbix重点笔记
- node文件服务器,nodejs一个简单的文件服务器的创建方法
- plc基础知识入门学习
- linux测坏道脚本,linux测试硬盘坏道
- 二进制部署多master节点的k8s集群-1.20以上稳定版本
- 2020美团秋招,二本计算机,疯狂复习半年,拿下美团offer
- uni-app 和H5页面视频播放flv格式视频监控
- 【人工智能算法从图解入手】
- Gradle build failed to produce an .apk file. It‘s likely that this file was generated under XXX
- h1283 linux内核,H1073C H1073 H1283升级失败恢复方法
- 因子分析,主成分分析,主因子分析,因子分析函数,极大似然法——数据分析与R语言 Lecture 12
热门文章
- springboot整合mybatis问题:ORA-00918: 未明确定义列
- 基于硬件的C(C++)语言程序设计教程4:计算货款
- go语言web开发出错
- 使用MPMoviePlayerController播放视频
- 【华为云·云筑2020】IOT考卷答案
- 地砖中间高四边低_地漏旁的瓷砖铺贴有讲究,千万不能乱贴
- 网购评论是真是假?文本挖掘告诉你
- 寒假-第一周-几何-(点线关系的问题)
- 详细讲解如何获取一串数字的个位、十位、百位.......等等
- implicit的用法