(我为更改问题而道歉)
以下代码片段来自MVC.NET控制器(.NET:v4.5; AspNet.MVC:v5.2.3)。 调用 LongOperation 后,它:
(为简单起见,我省略了代码)
所有这一切都有效,只有在 LongOperation 正在运行时,控制器才会处理其他 HTTP请求。
在 LongOperation 完成后处理,操作方法将结果返回给AJAX调用。
我搞砸了什么? 提前谢谢。
更新(适用于@angelsix评论): 这是一个简化的设置:
基本上:相同的结果,请参阅console.log-ed文本和时间戳 将感谢社区的任何帮助。 提前谢谢!
Action methods in the Controller
[AjaxOnly]
public ActionResult _RunLongOperation(string hubId)
{
try
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
ProgressNotifierHub.Notify(hubId, string.Format("Notification from _RunLongOperation {0}", i));
}
return new HttpStatusCodeResult(HttpStatusCode.OK, "_RunLongOperation : OK");
}
catch (Exception)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "_RunLongOperation : NOK");
}
}
[AjaxOnly]
public ActionResult _RunAnotherOperation(string hubId)
{
return new HttpStatusCodeResult(HttpStatusCode.OK, "_RunAnotherOperation : OK");
}
Razor View (partial) and javascript with SignalR hub setup Ajax calls
<script src="~/signalr/hubs"></script>
@{
Layout = null;
}
<button id="longOperationBtn" type="button" class="t-button" style='width: 155px'>Long Operation</button>
<button id="anotherOperationBtn" type="button" class="t-button" style='width: 155px'>Another Operation</button>
<script type="text/javascript">
$(function () {
setupEventHandlers();
setupProgressNorificator();
});
function setupEventHandlers() {
$('#longOperationBtn').click(function (event) {
requestOperation('_RunLongOperation')
});
$('#anotherOperationBtn').click(function (event) {
requestOperation('_RunAnotherOperation')
});
}
function requestOperation(method) {
trace(method + ' requested');
$.ajax({
url: '/Profiles/Validate/' + method,
type: 'GET',
data: { hubId: $.connection.hub.id },
contentType: 'application/json; charset=utf-8',
success: function () {
trace(method + ' completed');
},
error: function () {
trace(method + ' failed');
}
});
}
function setupProgressNorificator(profileId) {
var hub = $.connection.progressNotifierHub;
hub.client.notify = function (notification) {
console.log(notification);
};
$.connection.hub.start();
}
function trace(s) {
console.log('[' + new Date().toUTCString() + '] ' + s);
}
</script>
答案 0 :(得分:1)
看起来你正在运行客户端&#34;测试&#34;在Chrome上。我不确定2018的限制是什么(似乎从发行版到发行版),但浏览器确实限制了允许同一主机的并发连接数。我相信Chrome的限制是6或8。
您发布的日志似乎来自客户端。如果是,您所看到的行为实际上可能是客户端等待连接到服务器的免费连接 - 问题可能不在于ASP.NET,而在于您的测试方式。
验证很容易 - 编写另一个测试,您可以在一个单独的浏览器窗口中同时运行当前测试,该窗口只调用&#34; short&#34;操作。如果它有延迟,我错了。如果它没有,那么希望我能帮忙!
答案 1 :(得分:0)
您的回复没有提及有关缓存的任何内容。所以我怀疑浏览器正在缓存响应并使用它。
要验证在浏览器中按 F12 打开developer tools,然后查看第二个响应是否显示 304 或状态缓存< /强>
要防止对操作进行缓存,请执行此操作内的
Prevent Caching in ASP.NET MVC for specific actions using an attribute
答案 2 :(得分:0)
根据this:
某些......像 HTTP轮询(XHR)这样的协议每个客户端最多使用两个同时连接。重要的是要了解每个浏览器的最大连接数,而不是每个浏览器选项卡。尝试在同一浏览器中运行多个客户端可能会导致达到此限制。
就我而言,SignalR客户端正在使用长轮询。据报道,当使用Web套接字时,没有阻塞问题。关闭主题。 感谢Joe的帮助。
答案 3 :(得分:0)
您需要将控制器设置为具有只读会话状态行为。然后,您可以在运行长控制器方法期间向控制器执行ajax请求。在其他情况下(正如您所抱怨的那样),请求将排队并在完成控制器动作调用后立即调用所有请求。把它放在控制器类定义之前
[SessionState的(SessionStateBehavior.ReadOnly)]