我使用angular来发布到mvc控制器。然后这个控制器发送一堆电子邮件,这需要相当长的时间。是否有可能从服务器获得某种状态更新(比如说每发送50封电子邮件)?
角度代码:
$http.post('/users/send', { searchParams: $scope.search }).then(
function (data) {
$scope.status = data.data;
},
function (error) {
$scope.status = error;
}
);
Mvc:
[HttpPost]
public ActionResult SendEmail(SendEmailCriteria searchParams)
{
/*process and send emails*/
return Content(this.GetMessage(log.GetJson()));
}
答案 0 :(得分:1)
收到POST
请求后,将立即通过Guid
返回回复,电子邮件的发送将通过Task.Factory.StartNew
异步执行。您将在每次迭代后发送电子邮件并更新Progress
(或者您可以将其保存在Session
)。然后,要了解当前进度,您应该GET
请求新的Status
操作进行检查。需要Guid
才能将特定电子邮件的发送任务与相应的客户端连接,在POST
请求之后,您将定期(每5秒钟(不是每次50次迭代)通过{{1} })使用recivied $interval
作为查询参数调用Status
端点,以更新进度:
ASP.NET MVC:
guid
<强> AngularJS:强>
static Dictionary<Guid, int> Progress = new Dictionary<Guid, int>();
[HttpPost]
public ActionResult SendEmail(SendEmailCriteria searchParams)
{
var guid = Guid.NewGuid();
Task.Factory.StartNew(() => {
foreach(var email in emails)
{
Send(email);
Progress[guid] = (emails.IndexOf(email) + 1) * 100 / emails.Count;
}
});
return Json(new {guid});
}
[HttpGet]
public ActionResult Status(Guid guid)
{
var progress = Progress[guid];
if(progress == 100)
Progress.Remove(guid);
return Json(new {progress});
}
此外,您可以使用$http.post('/users/SendEmail', { searchParams: $scope.search }).then(
function (data) {
var interval = $interval(function(){
$http.get('/users/Status?guid=' + data.guid).then(
function(resp) {
$scope.progress = resp.progress;
if(resp.progress == 100)
$interval.cancel(interval);
},
function (error) {
$scope.status = error;
$interval.cancel(interval);
});
}, 5000);
},
function (error) {
$scope.status = error;
}
);
来通知客户已完成的工作,而无需定期服务器拉动。