日期:2014-05-17  浏览次数:20880 次

关于Session
Session使用确实很简单

string a = Session["test"].ToString();

Session有过期,所以一般这样用

if(Session["test"]!=null){
    string a = Session["test"].ToString();
}

但我纠结的是,假如session过期时刻刚好在if的条件判断与给a赋值之间。那这样的写法是不是还会报错?

于是我这样写

object test = Session["test"];
if (test != null)
{
    string a = test.ToString();
}

貌似object是引用类型,跟通常写法没区别?

虽然这样的折腾没多大意义,还是想请教大神帮忙理解下。
Session

------解决方案--------------------
在你的Page被创建以处理客户端请求之前,asp.net首先要把整个系统的Session数据集合中与这个Page所对应的SessionID相同的Session数据,拷贝到Page对象的Session集合里边来。

你的Page处理时间也许需要用0.5秒,当你的Page整个生命周期处理完,也就是这零点几秒之后,asp.net在销毁Page对象之前,会把这个Page对象实例中的Session集合中的多有数据再拷贝会整个系统的Session数据集合中。

asp.net需要不断地在整个系统的Session集合与每一个Page对象实例(在启动的单独线程上)内部的Session集合之间拷贝来拷贝去数据。

所谓“过期”,就是在刚刚创建Page对象实例、准备向其拷贝入Session数据之前,先去判断所有的SessionID,看看上一次拷贝回Session数据的最后操作时间,如果时间比较长则直接从系统Session集合中删除相同SessionID对应的数据。因此假设你设置为“20分钟后过期”,那么服务器端内存中的Session数据并不一会正好在20分钟之后就删除了,而是会在20分钟之后第一次客户端请求服务器(不管是当前的会话还是别的什么会话)时去删除。

比如说,现在有A、B、C共3个会话在线,其中A这个会话有20分钟没有访问过服务器,那么它对应的Session集合数据并不会在20分钟之后立刻删除掉。假设在22分钟之后,恰好有B会话访问了一下服务器,那么asp.net会首先判断A、B、C三个会话每一个是否超时,如果它判断A和C超时了,于是就会删除A和C的所有Session数据。删除了超时的Session数据之后,asp.net服务器才会开始创建B会话所请求的Page对象去处理客户端请求。因此A会话的Session数据此时实际上是22分钟后被删除的。

假设说asp.net开始处理B会话的请求、并删除A会话的Session数据的时候,此时A会话并没有处理页面请求,也就是根本没有“刚好在if的条件判断与给a赋值之间”这种操作,那么显然不会有你说的问题。

但是假设说A会话的一个Page正在处理请求,那么B会话的请求也还是会去立刻删除整个系统中Session集合里与A会话的SessionID对应的数据。但是,它跟此刻A会话所正在处理的Page对象(在启动的单独线程上的)里边的Session集合根本就是两个拷贝,因此并不会冲突。而且虽然B会话删除了系统中与A会话对应的Session的数据,可是当A会话的生命周期结束(0.5秒之后)asp.net系统就又把Page对象内部的Session值拷贝到整个系统的Session集合里了,因此即使此时A会话“超时”(超过20分钟)那么Session集合里边的数据也不会丢失的,而是会继续保持。