简体   繁体   English

AsyncController的异步操作阻止请求而不是立即返回

[英]AsyncController's async action blocks requests instead of returning immediately

This is the first time that I am using AsyncController (MVC3) and I am having trouble understanding the asynchronous action. 这是我第一次使用AsyncController(MVC3),我无法理解异步操作。 My task is to import moderate amount of data from Excel to SQL Server database, using Entity Framework. 我的任务是使用Entity Framework将适量的数据从Excel导入SQL Server数据库。 I thought this would qualify for an async operation and so I wrote a controller explicitly for that purpose. 我认为这有资格进行异步操作,所以我为此目的明确编写了一个控制器。 Here is the controller code with async Action 这是带有异步Action的控制器代码

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);

    }

I call the Async action (CampDonorImportAsync) using following JQuery code 我使用以下JQuery代码调用Async操作(CampDonorImportAsync)

    $.ajax({
        url: importDonorUrl,
        success: function (data, textStatus, jqXHR) {
            //Repeatedly call reportImportProgress
            refreshTimerId = window.setInterval(reportImportProgress, reportTaskProgressTime);
        },
    });

The reportImportProgress javascript function calls the ReportImportProgress() action which displays the current progress of the async action. reportImportProgress javascript函数调用ReportImportProgress()操作,该操作显示异步操作的当前进度。

    $.ajax({
        url: reportTaskProgressUrl,
        complete: function (jqXHR, textStatus, errorThrown) {
            var json = $.parseJSON(jqXHR.responseText);
            if (!json.CarryOn) {
                endImportInit();
                alert(json.Status);
            }
        },
    });

The issue is that the call to the Async method( CampDonorImportAsync ) blocks other requests from the same page, for example ReportImportProgress() above. 问题是对Async方法的调用( CampDonorImportAsync )阻止来自同一页面的其他请求,例如上面的ReportImportProgress() I thought that the call to Async action should return immediately, so that other requests can be made, even if the Async task is still going on. 我认为对Async操作的调用应立即返回,以便可以进行其他请求,即使Async任务仍在进行中。 I am not sure why the Async request gets blocked and waits for the task to complete, instead of returning immediately. 我不确定为什么Async请求被阻止并等待任务完成,而不是立即返回。 Any Ideas ? 有任何想法吗 ?

As I describe on my blog, async does not change the HTTP protocol . 正如我在博客中描述的那样, async不会改变HTTP协议 With HTTP, you get one response per request, and that's it. 使用HTTP,每个请求都会得到一个响应,就是这样。

A reliable solution is somewhat more complex than what you're thinking. 一个可靠的解决方案比你想的更复杂。 You need a reliable queue (eg, Azure queue) and an independent backend (eg, Azure worker role) that processes requests from that queue. 您需要一个可靠的队列(例如,Azure队列)和一个处理来自该队列的请求的独立后端(例如,Azure工作者角色)。 Then, your MVC controller can just add a request to the queue and return. 然后,您的MVC控制器可以只向队列添加请求并返回。 Your frontend can then poll for completion or be notified via something like SignalR. 然后,您的前端可以轮询完成或通过SignalR之类的通知进行通知。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM