2017-09-21 101 views
0

我有一个古老的asp.net网站我一直在慢慢地重构使用angularjs。我的一个页面调用了一个长时间运行的过程,我想让用户了解进度,并保持活动状态。在asp.net/angularjs中长时间运行进程的轮询进度

我想我可以通过使用一些angularjs比如下面的实现:

$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,调用startLongRunningProcess()这就要求MyPage.aspx/LongRunningProcessJson,然后调用pollProgress()作为预期。但是,它永远不会到达服务器上的MyPage.aspx/PollProgressJson。在服务器上长时间运行PROCESSS只是一个平常的WebMethod:

<WebMethod> 
Public Shared Function LongRunningProcessJson(...) As Result(Of String) 
    Dim service As LongRunningProcessService = GetService... 
    Return service.LongRunningProcess(..., HttpContext.Current.Session) 
End Function 

在这里,我用的是HTTP会话投放进度计数,所有PollProgressJson正在做的是查询该。

我不希望我到LongRunningProcessJson原来的呼叫完成,直到它完成,所以我应该做在那里的异步调用来完成所有的工作(和等待,直到它返回之前完成)?

或者,我采取了完全错误的方法? (是的,我知道,我不喜欢传递一个会话对象到我的业务层,它确实感到非常恶心)

我也试过使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

所以,事实证明,Asp.Net页面请求排队(通过召开会议锁定),其可能是写入同一会话,这只能在页面级别被关闭(当然,除非你的整个Web应用程序不需要它),而不是WebMethod级别。所以解决方案是加入:

<%@ Page .... EnableSessionState="ReadOnly" ...." %> 

我的页面指令,并删除使用Session写进度(我不喜欢这样做)。相反,您可以使用数据库,全局变量(yuk)或文件来存储&查询您的临时进度。

注:我相信在MVC您可以通过添加属性做在控制器级别同样的事情:

[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)] 
相关问题