解决方案 »

  1.   

    觉得楼主不必考虑这么多
    在session赋值中
    使用 try{} catch(){}
    捕获出现异常
      

  2.   

    尽量不要用session,极度耗费系统资源,而且有时候还会莫名其妙的丢失。用其它传值方式传值。
      

  3.   

    在你的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集合里边的数据也不会丢失的,而是会继续保持。
      

  4.   

    当你写的程序代码中使用Session集合的时候,你是在访问那个单独为Page生命周期处理所创建的线程的堆栈数据里的Session集合,它的数据当初从整个系统上的Session集合复制当前会话的Session数据到里边。在系统处理“Session过期”时,删除的是整个系统所管理的Session集合里的数据,根本不是单个Page对象所管理的Session集合,因此系统在删除 "test" 所对应的数据时,根本不是去删除 Page.Session["test"] 数据,永远也不可能遇到这种“刚好在if的条件判断与给a赋值之间”的情况。
      

  5.   

    尽管我们说Session集合里的数据会过期,但是我们要知道其过期的机制,免得胡乱猜忌自己的代码和胡乱编写程序。
      

  6.   


    超赞
    先前对Session的机制不了解不够,现在明白了,多谢~~