AsyncController的异步操作块请求,而不是立即返回 [英] AsyncController's async action blocks requests instead of returning immediately

查看:1183
本文介绍了AsyncController的异步操作块请求,而不是立即返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是第一次,我使用AsyncController(MVC3),我无法理解的异步操作。我的任务是从Excel导入数据量适中到SQL Server数据库,使用实体框架。我认为这将有资格获得异步操作,所以我写了明确的控制器用于这一目的。这里是控制器code。与异步操作

This is the first time that I am using AsyncController (MVC3) and I am having trouble understanding the asynchronous action. My task is to import moderate amount of data from Excel to SQL Server database, using Entity Framework. 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

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

    }

我打电话使用异步操作(CampDonorImportAsync)以下的JQuery code

I call the Async action (CampDonorImportAsync) using following JQuery code

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

JavaScript函数调用其中显示了异步操作的当​​前进度ReportImportProgress()动作的reportImportProgress。

The reportImportProgress javascript function calls the ReportImportProgress() action which displays the current progress of the async action.

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

问题是,在调用异步方法( CampDonorImportAsync )阻止其他来自同一个页面请求,例如 ReportImportProgress()以上。我认为,在调用异步行动应立即返回,以便其他请求可以做,即使异步任务仍在继续。我不知道为什么异步请求被阻断,用于任务等待完成的,而不是立即返回。任何想法?

The issue is that the call to the Async method(CampDonorImportAsync) blocks other requests from the same page, for example ReportImportProgress() above. 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. I am not sure why the Async request gets blocked and waits for the task to complete, instead of returning immediately. Any Ideas ?

推荐答案

当我描述我的博客上,的 异步不改变HTTP协议。借助HTTP,你会得到每个请求一个响应,仅此而已。

As I describe on my blog, async does not change the HTTP protocol. With HTTP, you get one response per request, and that's it.

一个可靠的解决方案是有点比你想什么更复杂。你需要一个可靠的队列(例如,天青队列)和一个独立的后端(例如,天青工作者角色)处理来自该队列的请求。然后,你的MVC控制器可以直接添加到队列和返回的请求。然后,您的前端可以查询完成,或者通过类似SignalR通知。

A reliable solution is somewhat more complex than what you're thinking. You need a reliable queue (e.g., Azure queue) and an independent backend (e.g., Azure worker role) that processes requests from that queue. Then, your MVC controller can just add a request to the queue and return. Your frontend can then poll for completion or be notified via something like SignalR.

这篇关于AsyncController的异步操作块请求,而不是立即返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆