这是我第一次使用AsyncController(MVC3)而我无法理解异步操作。我的任务是使用Entity Framework将适量的数据从Excel导入SQL Server数据库。我认为这有资格进行异步操作,所以我为此目的明确编写了一个控制器。这是带有异步操作的控制器代码
public class CampDonorImportController : AsyncController
{
public void CampDonorImportAsync(string fileName, int taskId) {
...
HttpContext.Application["Progress" + taskId] = 0;
AsyncManager.OutstandingOperations.Increment();
Task.Factory.StartNew(task => {
//Code to import Excel Data
}, taskId);
}
public ActionResult CampDonorImportCompleted() {
return null;
}
public ActionResult ReportImportProgress(int taskId) {
...
return Json(new { Progress = progress, CarryOn = carryOn, Status = status }, JsonRequestBehavior.AllowGet);
}
我使用以下JQuery代码调用Async操作(CampDonorImportAsync)
$.ajax({
url: importDonorUrl,
success: function (data, textStatus, jqXHR) {
//Repeatedly call reportImportProgress
refreshTimerId = window.setInterval(reportImportProgress, reportTaskProgressTime);
},
});
reportImportProgress javascript函数调用ReportImportProgress()操作,该操作显示异步操作的当前进度。
$.ajax({
url: reportTaskProgressUrl,
complete: function (jqXHR, textStatus, errorThrown) {
var json = $.parseJSON(jqXHR.responseText);
if (!json.CarryOn) {
endImportInit();
alert(json.Status);
}
},
});
问题是对异步方法的调用( CampDonorImportAsync )会阻止来自同一页面的其他请求,例如上面的 ReportImportProgress()。我认为对Async操作的调用应立即返回,以便可以进行其他请求,即使Async任务仍在进行中。我不确定为什么Async请求被阻止并等待任务完成,而不是立即返回。任何想法?
答案 0 :(得分:3)
正如我在博客中描述的async
does not change the HTTP protocol。使用HTTP,每个请求都会得到一个响应,就是这样。
可靠的解决方案比您的想法更复杂。您需要一个可靠的队列(例如,Azure队列)和一个处理来自该队列的请求的独立后端(例如,Azure工作者角色)。然后,您的MVC控制器可以只向队列添加请求并返回。然后,您的前端可以轮询完成或通过SignalR等信息通知。