【发布时间】:2018-04-06 23:23:12
【问题描述】:
(我为改变问题而道歉)
以下 sn-p 来自 MVC.NET 控制器 (.NET: v4.5; AspNet.MVC: v5.2.3)。 LongOperation 被调用后,它:
- 产生一个进程
- 等待完成
- 监控一些 LOG 文件
- 使用 SignalR 通知浏览器日志文件的进度
(为简单起见,我省略了代码)
所有这些都有效,只有在 LongOperation 运行时,控制器不会处理其他 HTTP 请求。
在LongOperation完成之后处理它们并且操作方法将结果返回给AJAX调用。
我在搞砸什么? 提前谢谢你。
更新(@angelsix 评论): 这是一个简化的设置:
- 我已按照建议删除了 async/await
- 按照建议添加断点
- 已验证它们已按上述说明命中
基本上:相同的结果,请参阅 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>
【问题讨论】:
-
澄清一下 - 长操作确实返回,已验证。
-
你能解释更多,比如添加你的场景的完整序列吗?
-
当然:我在加载文档时初始化 SignalR.js 集线器。单击按钮后,我对 _RunLongOperation 操作方法进行 AJAX 调用。它调用 LongOperaion() 方法,该方法生成一个外部进程,监视日志文件并通过 SignalR 集线器回复进度。这可行,但不可能有其他 HTTP 请求 - 在浏览器中的其他位置导航被阻止并在 AJAX 调用获得结果后继续。
-
我们需要查看两个调用的来源(审查调用),并且您是否在每个操作的开头放置一个断点,因为它们应该在调用时立即到达该操作,没有什么会阻止它跨度>
-
这不是 MVC 的工作方式。您阻止了一个操作方法,它不会阻止另一个调用。否则整个网络都会倒塌。想象整个谷歌网站一次只为数十亿个搜索结果提供服务? stackoverflow.com/questions/1763775/…。正如我之前提到的,我们仍然需要更多信息,因为您的代码现在是这样,没有阻塞问题。即使您说 Thread.Sleep(10000000) 您也可以立即拨打该电话两次没问题
标签: c# asp.net async-await signalr task