我有一个旧的asp.net网站我一直在慢慢重构使用angularjs。我的一个页面调用了一个非常长的运行过程,我想让用户随时了解进度,并保持会话处于活动状态。
我认为我可以通过使用如下的一些angularj来实现这一点:
$scope.setupLongRunningProcess= function() {
$scope.progress = {};
$scope.result = null;
startLongRunningProcess();
$timeout(function () {
pollProgress();
}, 5000);
}
function pollProgress() {
if (!$scope.result) {
$http({
method: "POST",
url: "MyPage.aspx/PollProgressJson",
data: {}
}).then(function successCallback(response) {
$scope.progress.Count = response.data.d;
$timeout(function() {
pollProgress();
}, 5000);
});
}
}
function startLongRunningProcess() {
$http({
method: "POST",
url: "MyPage.aspx/LongRunningProcessJson",
data: {}
}).then(function successCallback(response) {
$scope.result = response.data.d;
});
}
它开始OK,调用调用MyPage.aspx / LongRunningProcessJson的startLongRunningProcess(),然后按预期调用pollProgress()。但是,它永远不会到达服务器上的MyPage.aspx / PollProgressJson。服务器上长时间运行的进程只是一个常见的WebMethod:
<WebMethod>
Public Shared Function LongRunningProcessJson(...) As Result(Of String)
Dim service As LongRunningProcessService = GetService...
Return service.LongRunningProcess(..., HttpContext.Current.Session)
End Function
在这里,我使用Http Session来计算进度,所有PollProgressJson正在进行查询。
我不想让我对LongRunningProcessJson的原始调用完成,直到它完成,所以我应该在那里进行异步调用来完成所有工作(并等到它完成后再返回)?
或者,我采取了错误的方法吗? (是的,我知道,我不喜欢将Session对象传递给我的业务层,它确实感觉非常icky)
我也尝试过制作LongRunningProcessJson WebMethod异步,但不会调用PollProgressJson:
<WebMethod>
Public Shared Async Function LongRunningProcessJson(...) As Threading.Tasks.Task(Of Result(Of String))
Dim service As LongRunningProcessService = GetService...
Return Await Task.Run(Function() service.LongRunningProcess(..., HttpContext.Current.Session))
End Function
答案 0 :(得分:0)
您可以使用$ q service notify()函数来检查进度状态。详情请见https://docs.angularjs.org/api/ng/service/ $ q
答案 1 :(得分:0)
因此,事实证明,Asp.Net页面排队请求(通过持有会话锁定),可能正在写入同一个会话,这只能在页面级别关闭(除非当然,您的整个网络应用程序并不需要它,而不是WebMethod级别。所以解决方案是添加:
<%@ Page .... EnableSessionState="ReadOnly" ...." %>
到我的页面指令,并删除使用Session来编写进度(我还是不喜欢这样做)。相反,您可以使用数据库,全局变量(yuk)或文件来存储和查询您的临时进度。
注意:我相信MVC你可以通过添加属性在Controller级别做同样的事情:
[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]