我刚开始在我的项目中使用AsyncController来处理一些长时间运行的报告.因为我可以启动报告,然后在等待它返回并在屏幕上填充元素时执行一些其他操作,这似乎是理想的.
我的控制器看起来有点像这样.我试图使用一个线程执行长任务,我希望释放控制器以获取更多请求:
public class ReportsController : AsyncController
{
public void LongRunningActionAsync()
{
AsyncManager.OutstandingOperations.Increment();
var newThread = new Thread(LongTask);
newThread.Start();
}
private void LongTask()
{
// Do something that takes a really long time
//.......
AsyncManager.OutstandingOperations.Decrement();
}
public ActionResult LongRunningActionCompleted(string message)
{
// Set some data up on the view or something...
return View();
}
public JsonResult AnotherControllerAction()
{
// Do a quick task...
return Json("...");
}
}
Run Code Online (Sandbox Code Playgroud)
但我发现的是,当我使用jQuery ajax请求调用LongRunningAction时,我之后做的任何进一步的请求都会在它后面备份,直到LongRunningAction完成才会处理.例如,调用LongRunningAction需要10秒,然后调用不到一秒的AnotherControllerAction.AnotherControllerAction只是在返回结果之前等待LongRunningAction完成.
我还检查了jQuery代码,但如果我专门设置"async:true",这仍然会发生:
$.ajax({
async: true,
type: "POST",
url: "/Reports.aspx/LongRunningAction",
dataType: "html",
success: …Run Code Online (Sandbox Code Playgroud) 我有一个页面,列出了我们为客户监控的硬件设备.显示的每一行还显示设备的状态,即它是否正在运行,暂停,启动等.
为了改善页面加载时间,我列出了设备,但在呈现页面之前不会查询它们的状态.这是因为某些查询(例如通过SNMP或其他API)可能需要5-10秒才能响应.因此,对于十个设备的列表,用户可能需要一分钟才能看到空白页面.所以我做了以下事情 -
在设备列表页面上,我有以下脚本:
$(document).ready(function () {
var devices = $('div[name="runStatus"]');
devices.each(function () {
// Get device ID (I embed this using the HTML5 data-* attributes/annotations)
var deviceId = $(this).attr("data-deviceid");
var url = "/devmanager/status/" + deviceId;
$.getJSON(url, function (response) {
// Not actually important to the question...set text status, colours etc
$('div[data-deviceid="' + deviceId + '"]').text(response);
//...
});
});
});
Run Code Online (Sandbox Code Playgroud)
我发现如果我允许这个脚本运行,页面上的所有链接都会无响应.
我猜这是因为我有很多几乎并行的异步请求阻塞,直到他们从服务器得到响应并且某种程度上"UI线程"被这个阻止了?
但是我认为这不应该发生在AJAX上.
我发现在IE8,Chrome 8.0和Firefox 3.6中会发生这种"阻塞"行为.Chrome实际上显示了箭头光标+旋转 - 马桶 - 死亡(我正在使用Windows 7),就像页面没有完全呈现一样.
我怎样才能解决这个问题?
我有一个ASP.NET MVC3项目,主要的aspx页面使用jQuery ajax为其部件进行动态加载.所以基本上当网站加载时,它命中/ Home/Index然后在Index(aspx)视图中,有几行jQuery进行ajax调用(到/ Home/PartOne和/ Home/PartTwo来填充页面的部分内容).
因此,每次加载页面时,它基本上都会执行3个请求:获取索引,获取PartOne,然后获取PartTwo.
问题:为什么第三个请求执行会有某种"等待"时间?我认为这是浏览器并发请求限制,但为什么不在第一个请求完成后执行?
当我通过实验性地将"OutputCache"属性放在"PartTwo"上时,它表现得如预期的那样,它正在快速执行.这暗示问题不在IIS中,而是在此之后以及在它触及我的action方法之前的某个地方.
以下是Chrome网络探查器的屏幕截图:

这是MvcMiniProfiler上的屏幕截图 - 查看第3行/值,它在执行我的控制器动作代码之前等待500ms.

我的控制器代码看起来像这样.虽然我剪断了实际的代码,但PartTwo的代码非常简单(没有长时间的计算,没有数据库调用等):
public class HomeController : Controller {
public ActionResult Index() {
// do something here
return View();
}
public ActionResult PartOne() {
// do something here
return View();
}
public ActionResult PartTwo() {
// do something here
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
我的javascript:
$(document).ready(function () {
$.ajax({
url: "/Home/PartOne",
cache: false,
success: function (data, textStatus, request) {
$("#TestContainerOne").html(data);
}
});
$.ajax({
url: "/Home/PartTwo",
cache: false,
success: function (data, …Run Code Online (Sandbox Code Playgroud) ajax asp.net-mvc performance asp.net-mvc-3 mvc-mini-profiler
这是一个有趣的问题.
我正在做异步ajax put
return $.ajax({
url: url,
type: 'PUT',
contentType: 'application/json; charset=utf-8',
async: true, // default
success: function (result, textStatus, xhr) {...}
Run Code Online (Sandbox Code Playgroud)
这可以按预期工作,除非用户在前一次调用返回之前执行put(即使它是异步的,调用确实需要.5秒才能完成)
如果用户按下按钮几次(执行多次放置),则会发生以下情况:
这导致我不可避免的结论是第一个服务器回调触发了所有未完成的回调.
我可以在回调返回之前禁用该按钮,但是是否可以处理多个未完成的呼叫?这是浏览器的限制吗?处理这个的最佳方法?
UPDATE
作为测试我切换到使用POST而不是PUT:调整类型:JS端的'POST'和web api(服务器端)的[HttpPost].
行为没有改变.
UPDATE
看看像这样的帖子..这真的应该有效.我没有看到任何具体的原因,为什么其余的并发请求不会发送到服务器.