我在网上找了一个比较贴切的描述:

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的实现和区别相关推荐

  1. Session.Abandon和Session.Clear有何不同

    Session.Clear()就是把Session对象中的所有项目都删除了, Session对象里面啥都没有.但是Session对象还保留. Session.Abandon()就是把当前Session ...

  2. Session.Abandon和Session.Clear有何不同?

    主要的不同之处在于当使用Session.Abandon时,会调用Session_End方法(InProc模式下).当下一个请求到来时将激发Session_Start方法.而Session.Clear只 ...

  3. 11_Flask之Session 设置session有效期 获取session 删除session

    文章目录 1 什么是session? 2 实现session的两种思路 3 如何在flask中实现session? 3.1 设置session 3.2 设置session有效期 3.3 获取sessi ...

  4. Cookie、session和localStorage、以及sessionStorage之间的区别

    转载自https://www.cnblogs.com/zr123/p/8086525.html Cookie.session和localStorage.以及sessionStorage之间的区别 一. ...

  5. session传递参数_分布式 Session 之 Spring Session 架构与设计

    作者 | 李增光 杏仁后端工程师.「只有变秃,才能变强!」 ​前言 开始进行 Web 开发时,我们可能会遇到这样的情况,当服务器重启之后,之前的登录状态会失效需要重新登录.又或者你的应用程序部署了不止 ...

  6. Session分布式共享 = Session + Redis + Nginx

    一.Session 1.Session 介绍 我相信,搞Web开发的对Session一定再熟悉不过了,所以我就简单的介绍一下. Session:在计算机中,尤其是在网络应用中,称为"会话控制 ...

  7. php session 域,PHP session 跨子域问题总结

    今天,做项目时候遇到个问题.之前做东西的时候session一般就直接存在数据库中这样就能解决跨域 不仅仅是跨子域,但是今天遇到这个问题是,自己要在别人现有的东西上面做修改.由于仅仅是子域 当时就行肯定 ...

  8. session、flask session知识的相关收集

    1.打开两个浏览器窗口访问应用程序会使用同一个session还是不同的session session cookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的ses ...

  9. 利用spring session解决共享Session问题

    https://blog.csdn.net/patrickyoung6625/article/details/45694157 1.共享Session问题 HttpSession是通过Servlet容 ...

最新文章

  1. aes前台加密后台解密
  2. 敲黑板了!网络推广软件教你如何有效提高网站权重?
  3. Zookeeper分布式一致性原理(九):Zookeeper分布式应用
  4. [转载]漫谈游戏中的阴影技术
  5. SAP Spartacus pageSlot一览
  6. 数据结构---prim最小生成树
  7. python - 输出最大/最小的 k 个元素的索引
  8. DeOccNet:国防科大提出阵列相机去除前景遮挡成像新方法
  9. 浅析类的const成员函数,类的const对象
  10. zabbix重点笔记
  11. node文件服务器,nodejs一个简单的文件服务器的创建方法
  12. plc基础知识入门学习
  13. linux测坏道脚本,linux测试硬盘坏道
  14. 二进制部署多master节点的k8s集群-1.20以上稳定版本
  15. 2020美团秋招,二本计算机,疯狂复习半年,拿下美团offer
  16. uni-app 和H5页面视频播放flv格式视频监控
  17. 【人工智能算法从图解入手】
  18. Gradle build failed to produce an .apk file. It‘s likely that this file was generated under XXX
  19. h1283 linux内核,H1073C H1073 H1283升级失败恢复方法
  20. 因子分析,主成分分析,主因子分析,因子分析函数,极大似然法——数据分析与R语言 Lecture 12

热门文章

  1. springboot整合mybatis问题:ORA-00918: 未明确定义列
  2. 基于硬件的C(C++)语言程序设计教程4:计算货款
  3. go语言web开发出错
  4. 使用MPMoviePlayerController播放视频
  5. 【华为云·云筑2020】IOT考卷答案
  6. 地砖中间高四边低_地漏旁的瓷砖铺贴有讲究,千万不能乱贴
  7. 网购评论是真是假?文本挖掘告诉你
  8. 寒假-第一周-几何-(点线关系的问题)
  9. 详细讲解如何获取一串数字的个位、十位、百位.......等等
  10. implicit的用法