下面是我写的一个sample,先上代码:
public class HomeController : Controller { // // GET: /Home/ public ActionResult Index() { return View(); } public ActionResult Test() { System.Threading.Thread.Sleep(30000); return View(); } }
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } protected void Session_Start(object sender, EventArgs e) { } }
这时当我打开浏览器打开两个tab,先在一个tab中打开/Home/Test,这时这个tab会等30秒才能呈现页面,在这期间我在另一个tab中打开/Home/Index,而搞不明白的是,只有等第一个tab30秒过后,第二个tab才能呈现/Home/Index。请大神指导这是为什么?
问题已经解决了,详见 http://www.cnblogs.com/CoderZicode/p/3863050.html
你把session_start删了就没问题?
嗯
@CoderZ: 你的session是inproc的还是stateserver还是sqlserver?
@飞来飞去: 确实是个奇怪的问题,之前一直没注意过。我在我的VS2010上建MVC2的工程,能重现这个问题。在页面上打出当前的Session.SessionID,然后在添加和没有添加Session_Start两种情况下打开页面,没有添加Session_Start的时候每次刷新SessionID都不同,但是添加之后重新打开页面,每次刷新这个值都一样。看似Session_Start会对回话的创建有影响。有时间研究一下。
@飞来飞去: 谢谢你提示,我试了session的5个mode,除了"Off"(根本不会触发Session_Start了),其他都不可以。
这有什么好奇怪的.第一次请求还没响应,会话还没开始,第二次请求还是一个新请求,当然会这样了,
你看下第二个请求报文里应该是没有会话ID的`
请问你仔细考虑过了么?我是在controller里等待30秒,在Session_Start之后,所以第一次请求session已经创建了,第二次请求会和第一次用同一个SessionId。如果是用两个sessionId,比如两个浏览器而不是两个tab,是不会复现的。
@CoderZ: 仔细考虑过了的```你在控制器阻塞了30秒,这时响应还没有到达浏览器,也就是说浏览器的cookie中此时并没有会话ID,这样你第二次请求发送是是不会有会话ID的,所以对服务器来说第二次请求又是一个新会话,
@吴瑞祥: 但它们确实是使用同一个sessionID。在debug下可以看到只有第一个tab的session_start事件被触发了。我觉得你说的有一定道理,我也不知道为什么有这种结果。我的问题已经解决了,需要设置[SessionState(SessionStateBehavior.ReadOnly)] 可以解决,这样它会对同一个session并行处理请求而不是按顺序处理。
@CoderZ: 肯定只会有一个会话ID的,因为第一次请求的会话ID被第二次的会话ID覆盖了```
你是被自己绕进去了..你在控制器返回时把当前会话ID输出到页面上就会发现2个会话ID不一样了
COOKIE会因为同域被直接覆盖的
@吴瑞祥:好的,我研究一下,谢谢你~