Kev*_*Kev 73 javascript ajax asp.net-mvc jquery asp.net-mvc-2
几天前我问了这个问题:
我在同一个控制器动作中同时发出六个jQuery async ajax请求.每个请求需要10秒才能返回.
通过调试和记录对action方法的请求,我注意到请求是序列化的,并且永远不会并行运行.即我在我的log4net日志中看到一个时间轴,如下所示:
2010-12-13 13:25:06,633 [11164] INFO - Got:1156 2010-12-13 13:25:16,634 [11164] INFO - Returning:1156 2010-12-13 13:25:16,770 [7124] INFO - Got:1426 2010-12-13 13:25:26,772 [7124] INFO - Returning:1426 2010-12-13 13:25:26,925 [11164] INFO - Got:1912 2010-12-13 13:25:36,926 [11164] INFO - Returning:1912 2010-12-13 13:25:37,096 [9812] INFO - Got:1913 2010-12-13 13:25:47,098 [9812] INFO - Returning:1913 2010-12-13 13:25:47,283 [7124] INFO - Got:2002 2010-12-13 13:25:57,285 [7124] INFO - Returning:2002 2010-12-13 13:25:57,424 [11164] INFO - Got:1308 2010-12-13 13:26:07,425 [11164] INFO - Returning:1308
查看FireFox中的网络时间线,我看到了:
上面的日志示例和Firefox网络时间线都针对同一组请求.
来自同一页面的同一操作的请求是否已序列化?我知道Session
在同一会话中对对象的序列化访问,但没有触及会话数据.
我将客户端代码剥离为单个请求(运行时间最长)但仍会阻止浏览器,即只有当ajax请求完成时,浏览器才会响应任何链接点击.
我在这里(在Chrome的开发人员工具中)观察到的是,在执行长时间运行的ajax请求时单击链接时,它会Failed to load resource
立即报告错误,这表明浏览器已经杀死(或者正试图杀死并等待?)ajax请求:
但是,浏览器仍需要一个年龄才能重定向到新页面.
ajax请求是否真的是异步的,或者这很简单,因为javascript实际上是单线程的?
我的要求是否需要花费太长时间才能完成这项工作?
问题也出现在Firefox和IE中.
我还将脚本更改为$.ajax
直接使用并明确设置async: true
.
我在IIS7.5上运行它,Windows 2008R2和Windows 7版本都做同样的事情.
调试和发布版本的行为也相同.
Kev*_*Kev 89
答案是盯着我的脸.
对会话状态的访问是每个会话独占的,这意味着如果两个不同的用户发出并发请求,则同时授予对每个单独会话的访问权限.但是,如果对同一会话发出两个并发请求(通过使用相同的SessionID值),则第一个请求将获得对会话信息的独占访问权.第二个请求仅在第一个请求完成后执行.
令人讨厌的是,几周前我已经撇去了一段并没有真正考虑到大胆句子的全部影响.我已经读过,只是"访问会话状态是序列化的"而不是"所有请求,无论你是否触摸会话状态,都被序列化",如果请求来自同一个会话.
幸运的是,ASP.NET MVC3中有一个可行的方法,它可以创建无会话控制器.Scott Guthrie在这里谈到这些:
我安装了MVC3 RC2并升级了项目.装饰有问题的控制器[SessionState(SessionStateBehavior.Disabled)]
解决了这个问题.
当然,通常我几分钟前在Stack Overflow中发现了这个:
我试图重现这个但是无法重现.这是我的测试:
private static readonly Random _random = new Random();
public ActionResult Ajax()
{
var startTime = DateTime.Now;
Thread.Sleep(_random.Next(5000, 10000));
return Json(new {
startTime = startTime.ToString("HH:mm:ss fff"),
endTime = DateTime.Now.ToString("HH:mm:ss fff")
}, JsonRequestBehavior.AllowGet);
}
Run Code Online (Sandbox Code Playgroud)
电话:
<script type="text/javascript" src="/scripts/jquery-1.4.1.js"></script>
<script type="text/javascript">
$(function () {
for (var i = 0; i < 6; i++) {
$.getJSON('/home/ajax', function (result) {
$('#result').append($('<div/>').html(
result.startTime + ' | ' + result.endTime
));
});
}
});
</script>
<div id="result"></div>
Run Code Online (Sandbox Code Playgroud)
结果如下:
13:37:00 603 | 13:37:05 969
13:37:00 603 | 13:37:06 640
13:37:00 571 | 13:37:07 591
13:37:00 603 | 13:37:08 730
13:37:00 603 | 13:37:10 025
13:37:00 603 | 13:37:10 166
Run Code Online (Sandbox Code Playgroud)
和FireBug控制台:
正如您所看到的,AJAX操作是并行执行的.
更新:
似乎在我的初始测试中,使用时,请求确实在FireFox 3.6.12和Chrome 8.0.552.215中排队$.getJSON()
.它在IE8中工作正常.我的测试是使用ASP.NET MVC 2项目,VS2010,Cassini Web服务器,Windows 7 x64位执行的.
现在,如果我更换$.getJSON()
与$.get()
它在所有的浏览器工作正常.这让我相信这有$.getJSON()
可能导致请求排队的东西.也许更熟悉jQuery框架内部的人能够更多地了解这个问题.
更新2:
尝试设置cache: false
:
$.ajax({
url: '/home/ajax',
cache: false,
success: function (result) {
$('#result').append($('<div/>').html(
result.startTime + ' | ' + result.endTime
));
}
});
Run Code Online (Sandbox Code Playgroud)