ASP.NET Session的七点认识小结
ASP.NET Session的深入理解与常见七点问题
在ASP.NET Web应用程序中,Session对象扮演着存储用户状态信息的重要角色。在使用过程中,我们常常会遇到许多关于Session的问题。这里,我们将详细一些常见的ASP.NET Session相关的问题及其解决方法。
一、Session中的值类型变量理解
在Session中保存值类型变量时,实际上保存的是该变量的拷贝。例如,当执行语句Session["__test0"] = 1后,如果从Session中取出该值并尝试修改,如int i = (int)Session["__test0"]+1,并不会影响Session中原有值。这是因为Session中保存的是值的副本,所以i的值会增加,而Session中的值保持不变。
二、引用类型变量的Session理解
对于引用类型的变量,Session中保存的是对象的引用。例如,当创建一个DataSet对象并将其保存到Session中,如果后续对该DataSet对象进行修改,Session中的对象也会相应改变。这是因为Session中保存的是对象的引用,而不是对象的拷贝。
三、Session周期与浏览器窗口的关系
新的浏览器窗口启动后,会开始一个新的Session,触发Global的Session_Start事件。从同一个浏览器窗口打开的子窗口不会启动新的Session。Session过期后,执行页面的提交也会触发Session_Start事件,相当于开始一个新的Session。
四、Web Service中的Session调用
在Web Service中,每个方法的调用都会启动一个Session。为了实现多个调用在同一个Session中进行,可以使用CookieContainer来管理不同代理的Cookie。只要多个代理的CookieContainer属性设置为相同的值,则对这些Web Service的调用会保持在同一个Session中。
五、Session数据有效期
只要页面有提交活动,Session中的所有数据项都会保持有效。如果在20分钟内(默认配置)页面没有任何提交活动,Session会失效。需要注意的是,Session内存储的多个数据项是整体失效的。
六、Session的保存与序列化
在Session中保存非序列化的类(如DataView)时,如果使用SQLServer保存Session的模式,可能无法正常使用。要查看一个类是否可序列化,需要查看该类是否用[Serializable]进行了标记。
七、关于Session的清除与内存释放问题
在Session中保存大量数据时,如DataSet,可能会导致asp_wp.exe占用大量内存。当退出使用这些数据的页面后,即使使用Session.Clear()或DataSet.Clear()方法,内存的占用可能仍然无法降低。这是因为Session ID仍然在服务器上保持活动状态,即使Session过期,内存占用也可能不会立即释放。解决这个问题的一种方法是使用会话超时设置来自动结束会话,或者手动结束会话并重启服务器以释放内存。还需要注意会话ID的管理和浏览器窗口的关闭行为对会话状态的影响。
ASP.NET Session是一个重要的用户状态管理工具,但在使用过程中需要注意其特性和限制。通过理解这些问题并采取相应的措施,我们可以更好地管理和优化Web应用程序中的会话状态。在VS中创建一个简单的ASP.NET Web应用程序,并在Web Form1上添加一个按钮。通过在页面的Page_Load事件中启用Trace功能,我们可以浏览此页面并连续点击按钮以提交请求。借助ASP.NET的Trace功能,我们可以观察到Session ID在每次点击按钮时都在不断变化。这表明在服务器端,每次的请求都被视为来自一个新的客户端。这是怎么回事呢?
为了更好地理解这一现象,我们可以在Page_Load事件中添加一行代码:session["variable1"]="testvalue"。当我们再次进行测试时,我们会发现Session ID保持一致。这一观察让我们明白,为了建立一个持续的Session,我们至少需要向Session变量中写入一次数据。换句话说,我们要向Session dictionary中至少添加一项内容。这仅仅是一个必要条件,并非充分条件。
在下一个必要条件之前,我们需要明确一点:如果在程序中包含Global.asax文件,并且在该文件中定义了Session_OnStart和Session_OnEnd处理函数,那么之前的实验将无法成功进行。这是因为一旦定义了Session_OnStart处理函数,Session的状态始终会被保存,即使它是空的。这样,Session ID就不会改变。考虑到Session会消耗资源,因此在ASP.NET Web应用程序中,除非有必要,否则不应将Session_OnStart和Session_End写在Global.asax文件中。
在我们的实验中,当Session ID在变化时,我们无法追踪到Session_OnEnd的执行。一旦Session ID保持稳定,Session_OnEnd就会出现。现在,让我们进一步另一个条件。在包含Session_OnStart和Session_OnEnd的例子的基础上,我们在Page_Load事件的Session代码后添加一句:session.Abandon()。当我们运行程序时,会发现尽管Session_OnStart已经执行过一次,但Session_OnEnd并没有执行。如果我们把session.Abandon()放在Button的OnClick事件中,Session_OnEnd就会立即执行。这里的区别在于,要让Session_OnEnd成功执行,至少需要一个完整的Request已经执行。在Page_Load中就中止程序的话,第一个Request都没有执行完毕,Session_OnEnd就无法触发。
结合这两个必要条件,我们得出了使Session_OnEnd执行的充分条件:
1. 至少有一个Request成功完整地执行;
2. 在Session状态中至少存储一些数据。这可以通过使用Session变量或添加Session_OnStart来实现。值得注意的是,Session_OnEnd仅在InProc模式中得到支持,也就是当Session数据在ASP.NET worker process中时。
关于ASP.NET Session的七点认识就分享到这里,希望对你理解ASP.NET Session有所帮助。让我们继续更多ASP.NET的奥秘吧!
微信营销
- ASP.NET Session的七点认识小结
- vue mint-ui学习笔记之picker的使用
- Bootstrap3学习笔记(二)之排版
- php出租房数据管理及搜索页面
- nodeJS微信分享
- BootStrap 页签切换失效的解决方法
- PHP封装请求类实例分析【基于Yii框架】
- PHP实现的浏览器检查类
- 同一个帐号不能同时登陆的问题
- 浅谈javascript中关于日期和时间的基础知识
- JavaScript实现的圆形浮动标签云效果实例
- jQuery Mobile弹出窗、弹出层知识汇总
- [js高手之路]图解javascript的原型(prototype)对象,原型
- PHP设置images目录不充许http访问的方法
- 如何使用微信公众平台开发模式实现多客服
- iview Upload组件多个文件上传的示例代码