Asp.net mvc 异步控制器';s异步操作阻止请求,而不是立即返回

Asp.net mvc 异步控制器';s异步操作阻止请求,而不是立即返回,asp.net-mvc,asp.net-mvc-3,asynccontroller,Asp.net Mvc,Asp.net Mvc 3,Asynccontroller,这是我第一次使用AsyncController(MVC3),我在理解异步操作时遇到了困难。我的任务是使用实体框架将适量的数据从Excel导入SQL Server数据库。我认为这符合异步操作的条件,因此我明确为此目的编写了一个控制器。以下是具有异步操作的控制器代码 public class CampDonorImportController : AsyncController { public void CampDonorImportAsync(string fileName, int t

这是我第一次使用AsyncController(MVC3),我在理解异步操作时遇到了困难。我的任务是使用实体框架将适量的数据从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代码调用异步操作(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()。我认为对异步操作的调用应该立即返回,这样即使异步任务仍在进行,也可以发出其他请求。我不知道为什么异步请求会被阻止并等待任务完成,而不是立即返回。有什么想法吗?

正如我在博客上描述的那样。使用HTTP,每个请求都有一个响应,就是这样


可靠的解决方案比您所想的要复杂一些。您需要一个可靠的队列(例如Azure队列)和一个独立的后端(例如Azure worker角色),用于处理来自该队列的请求。然后,您的MVC控制器可以向队列中添加一个请求并返回。然后,您的前端可以轮询完成,或者通过信号器之类的方式得到通知。

是的,我有点误解了整个异步操作。只有IIS线程返回到池中,请求仍然有效。事实上,我偶然发现了一个可行的解决方案。这里是链接。实际上,启动新任务的操作方法返回(不等待后台任务),然后我可以定期调用我的ReprotImportProgress操作。它是有效的,但我不确定它的缺点(如果有的话)@Nirvan:将长时间运行的任务像你发布的链接一样保存在内存中是相当危险的。我已经详细介绍了这一点,我已经实现了你在博客文章中提到的解决方案。我已经对它进行了测试,取消令牌功能允许任务正常退出。通常,我们会在后台处理之前备份数据库,因此您的解决方案非常适合我的情况。