1

这是我第一次使用 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);
            }
        },
    });

问题是对 Async 方法 ( CampDonorImportAsync ) 的调用会阻止来自同一页面的其他请求,例如上面的ReportImportProgress()。我认为对 Async 操作的调用应该立即返回,以便可以发出其他请求,即使 Async 任务仍在进行中。我不确定为什么异步请求被阻止并等待任务完成,而不是立即返回。有任何想法吗 ?

4

1 回答 1

3

正如我在博客中所描述的,async不会更改 HTTP 协议。使用 HTTP,每个请求都会得到一个响应,仅此而已。

可靠的解决方案比您想象的要复杂一些。您需要一个可靠的队列(例如,Azure 队列)和一个独立的后端(例如,Azure 辅助角色)来处理来自该队列的请求。然后,您的 MVC 控制器可以将请求添加到队列并返回。然后,您的前端可以轮询完成或通过 SignalR 之类的东西获得通知。

于 2013-12-05T14:14:02.877 回答