Async MVC.NET操作方法阻止任何其他HTTP请求

(我为改变问题而道歉)

以下代码片段来自MVC.NET控制器(.NET:v4.5; AspNet.MVC:v5.2.3)。 调用LongOperation后,它:

  • 产生一个过程
  • 等待完成
  • 监视一些LOG文件
  • 使用SignalR从LOG文件通知浏览器进度

(为简单起见,我省略了代码)

所有这一切都有效,只有在LongOperation运行时,控制器才会处理其他 HTTP请求。

LongOperation完成处理它们并且action方法将结果返回给AJAX调用。

我搞砸了什么? 先感谢您。

在此处输入图像描述

更新(对于@angelsix评论):这是一个简化的设置:

  • 我已根据建议删除了async / await
  • 根据建议添加断点
  • 已validation它们如上所述被击中

基本上:相同的结果,请参阅console.log-ed文本和时间戳欢迎来自社区的任何帮助。 先感谢您!

GUI和日志 GUI和日志

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(部分)和带有SignalR集线器的javascript设置Ajax调用

  @{ Layout = null; }    $(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); }  

看起来您在Chrome上运行客户端“测试”。 我不确定2018的限制是什么(它似乎从发行版到发行版),但浏览器确实限制了允许同一主机的并发连接数。 我相信Chrome的限制是6或8。

您发布的日志似乎来自客户端。 如果是,您所看到的行为实际上可能是客户端等待连接到服务器的免费连接 – 问题可能不在于ASP.NET,而在于您的测试方式。

validation很容易 – 在另一个只调用“短”操作的浏览器窗口中编写另一个可以与当前测试同时运行的测试。 如果它有延迟,我错了。 如果没有,希望我帮忙了!

问题

您的回复没有提及有关缓存的任何信息。 所以我怀疑浏览器正在缓存响应并使用它。

校验

要validation在浏览器中按F12打开开发人员工具 ,然后查看第二个响应是否显示状态304或状态缓存

解决

要防止对操作进行缓存,请在要执行此操作的操作内部

使用属性阻止ASP.NET MVC中的缓存以执行特定操作

根据这个 :

某些…… HTTP轮询(XHR)等协议每个客户端最多使用两个同时连接 重要的是要了解每个浏览器的最大连接数,而不是每个浏览器选项卡。 尝试在同一浏览器中运行多个客户端可能会导致达到此限制。

就我而言,SignalR客户端正在使用长轮询。 据报道,当使用Web套接字时,没有阻塞问题。 关闭主题。 谢谢Joe的帮助。

您需要将控制器设置为具有只读会话状态行为。 然后,您可以在运行长控制器方法期间向控制器执行ajax请求。 在其他情况下(正如您所抱怨的那样),请求将排队并在完成控制器动作调用后立即调用所有请求。 把它放在控制器类定义之前

[SessionState的(SessionStateBehavior.ReadOnly)]