会话Session

  • Session用于服务器端状态管理,使用Session之后,每个客户端都可以将实际的数据保存在服务器上,对于每个客户端的数据,将会生成一个对应的唯一的key(保存在客户端)。客户端与服务器端就是通过这个key来确认客户端的身份,通常这个key为SessionID。
  • 一般情况下,SessionID以Cookie的形式保存在浏览器中,在不使用Cookie的情况下,也可以将这个SessionID嵌入到访问网页的URL中。

服务器端Session

在页面对象或者HttpContext对象中,都有一个名为Session的属性,在一次会话中,它们引用的都是同一个对象。

public HttpSessionState Session { get; }

Session对象是HttpSessionState类的实例。Session是保存在服务器端的,对每个登录到网站的用户都有一份,是独有的,而其他用户无法共享。


那么问题来了,来看看奇怪的阻塞。

我们来看一个一需求: 需要实时的将服务器的运行状态输出到当前登陆的客户端,建立长连接并且作实时输出。 然后就有了下面这个Action。

Boolean isOnline = true;

 public ActionResult Index()
{
#region 滚动条控制 Response.Write("<html onclick=\"clearInterval(i_1);\" ondblclick =\"reInterval()\"><head><title>服务器实时监控</title></head>");
Response.Write("<script type=\"text/javascript\">");
Response.Write("function scrollWindow() { document.body.scrollTop = document.body.scrollHeight; }");
Response.Write("function reInterval() { i_1 = setInterval('scrollWindow()', 50); }");
Response.Write("i_1 = setInterval('scrollWindow()', 50);");
Response.Write("scrollWindow();");
Response.Write("</script> ");
Response.Flush(); #endregion Dictionary<int, string> dicColor = new Dictionary<int, string>()
{
{,"#0000FF"}, // 蓝色
{,"#FF3333"}, // 红色
{,"#FFFF00"}, // 黄色
{,"#FF3EFF"},
{,"#0000FF"},
{,"#0000FF"}
};
DebugCallback callback = new DebugCallback(delegate(int type, string str)
{
if (dicColor.ContainsKey(type))
{
Response.Write("<span style = 'color:" + dicColor[type] + ";'>" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "--" + str + "</span> <br />");
}
Response.Flush();
}); Log.AddCallBack(callback); while (isOnline)
{
try
{
Response.Write("...<br>");
Response.Flush();
}
catch { }
System.Threading.Thread.Sleep();
if (!Response.IsClientConnected) // 连接关闭
{
Log.RemoveCallBack(callback);
Response.Write("</html>");
break;
}
}
return null;
}

由于这个Action是一个长连接,它不会断开连接会一直处于请求的状态,这个时候当我们再请求同一个Session的其它的Action的时候,发现所有其它的Action都会处于Waiting状态……好吧,明明是异步并发请求,为何现在却成了“单线程”工作了呢?很明显有锁。


原因

  • HttpSessionState来自于HttpModule的SessionStateModule。在每次请求处理过程中,HttpApplication的请求的处理管道中会检查当前请求的处理程序是否实现了接口IRequiresSessionState,如果实现的话,那么SessionStateModule将为这个请求分配HttpSessionState。同时SessionStateModule还负责SessionID的生成、Cookieless会话管理、从外部状态提供程序中检索会话数据以及将数据绑定到请求的调用上下文。
  • 如果页面请求设置一个读取器锁定,同一会话中同时处理的其他请求将无法更新会话状态,但是至少可以进行读取。如果页面请求为会话状态设置一个写入锁,那么所有其他页面都被阻止,无论他们是否要读取或写入内容。例如,如果同时有两段程序视图在同一个Session中写入内容,一段程序必须等到另一段程序完成后才能写入。在AJAX程序设计中,必须注意这种情况的发生。

解决方法

对于Asp.net MVC:

可以为本Controller增加以下特性,但是本Controller都不能修改Session了,只能读取

[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]

对于Asp.net WebForm:

在Web.config 文件里面添加

EnableSessionState="ReadOnly" // 仅仅加载那个阻塞页面

ASP.net Session阻塞、Session锁、MVC Action请求阻塞问题的更多相关文章

  1. asp.net session锁导致ajax请求阻塞

    问:为了可以顺序访问Session的状态值,Session是否提供了锁定机制?答:Session实现了Reader/Writer的锁机制:当页面对Session具有可写功能(即页面有<%@Pag ...

  2. PHP自带Session隐患(session文件独占锁引起阻塞)

    PHP自带Session隐患(session文件独占锁引起阻塞) PHP默认的会话处理器是session.save_handler = files(即文件).如果同一个客户端同时并发发送多个请求(如a ...

  3. [转]Asp.Net大型项目实践(11)-基于MVC Action粒度的权限管理【续】【源码在这里】(在线demo,全部源码)

    本文转自:http://www.cnblogs.com/legendxian/archive/2010/01/25/1655551.html 接上篇Asp.Net大型项目实践(10)-基于MVC Ac ...

  4. Asp.net 服务器Application,Session,Cookie,ViewState和Cache区别

    2.8 Context 的使用Context 对象包含与当前页面相关的信息,提供对整个上下文的访问,包括请求.响应.以及上文中的Session 和Application 等信息.可以使用此对象在网页之 ...

  5. PHP - 请求阻塞,Session写阻塞

    之前写某些代码的时候,发现用户莫名奇妙地阻塞了,而且这种阻塞的情况还比较难以形容: 使用session过程中,在开启session后,同一浏览器,执行同一程序,不同页面会被锁.不同浏览器不会出现这种情 ...

  6. ASP.NET中的Session怎么正确使用

    Session对象用于存储从一个用户开始访问某个特定的aspx的页面起,到用户离开为止,特定的用户会话所需要的信息.用户在应用程序的页面切换时,Session对象的变量不会被清除. 对于一个Web应用 ...

  7. ASP.NET里的Session详细解释

    Session模型简介 Session是什么呢?简单来说就是服务器给客户端的一个编号.当一台WWW服务器运行时,可能有若干个用户浏览正在运正在这台服务器上的网站.当每个用户首次与这台WWW服务器建立连 ...

  8. [转]ASP.Net篇之Session与Cookie

    本文转自:http://www.cnblogs.com/japanbbq/archive/2011/08/31/2160494.html Session: Session是“会话”的意思,然而,因为h ...

  9. ASP.NET中的Session怎么正确使用[转]

    Session对象用于存储从一个用户开始访问某个特定的aspx的页面起,到用户离开为止,特定的用户会话所需要的信息.用户在应用程序的页面切换时,Session对象的变量不会被清除. 对于一个Web应用 ...

随机推荐

  1. 没有定义json_encode()函数。

    php5是没有json扩展的,需要自行下载. 命令php -m 可以查看安装了哪些扩展. 1.修改php.ini 在php.ini 中加入 extension=json.so:sudo vi /etc ...

  2. python 里 np.array 的shape (2,)与(2,1)的分别是什么意思,区别是什么?

    numpy.ndarray.shap是返回一个数组维度的元组. (2,)与(2,1)的区别如下:   ndarray.shape:数组的维度.为一个表示数组在每个维度上大小的整数元组.例如二维数组中, ...

  3. ProtoBuf练习(一)

    基础数据类型 protobuf语言的基础字段类型相当于C++语言的基础类型 工程目录结构 $ ls proto/ TFixed.proto TInt.proto TScalar.proto TStr. ...

  4. Docker 容器的数据卷

    数据卷的特点: 1. 数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,这些数据会拷贝到新初始化的数据卷中 2. 数据卷可以在容器之间共享和重用 3. 可以对数据卷里的内容直接进行修改 ...

  5. 《OD面试》Java软件工程师

    一.JVM自动内存管理机制 1. Java内存模型 1.1 由所有线程共享的数据区: 1.1.1 方法区(Method Area), Non-Heap(非堆) 用户存储已被虚拟机加载的类信息.常量.静 ...

  6. 图解Linux安装jdk

    测试是否安装成功: 查看Java的版本命令:java -version Windows:查看java版本的方法是:运行--->cmd,输入java –version.注意: linux:终端中输 ...

  7. 2017-10-15 NOIP模拟赛

    Stack #include<iostream> #include<cstdio> #define mod 7 using namespace std; ][],n; int ...

  8. 洛谷P1092 虫食算

    P1092 虫食算 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: http://paste.ubuntu.com/2544 ...

  9. rem 回家测试

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. Command模式(命令设计模式)

    Command?? 把方法的调用用一个类的实例来承载,要管理工作的历史记录,创建这些方法执行的命令的集合,只需管理这些实例的集合即可,而且还可以随时再次执行过去的命令,或是将多个过去的命令整合为一个新 ...