1

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 コードを使用して、非同期アクション (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()など) をブロックすることです。非同期タスクがまだ進行中であっても、他のリクエストを行うことができるように、非同期アクションの呼び出しはすぐに返されるはずだと思いました。非同期リクエストがブロックされ、すぐに戻るのではなく、タスクが完了するのを待つ理由がわかりません。何か案は ?

4

1 に答える 1

3

ブログで説明しているように、asyncは HTTP プロトコルを変更しません。HTTP では、リクエストごとに 1 つのレスポンスを取得します。それだけです。

信頼できるソリューションは、あなたが考えているよりもやや複雑です。信頼できるキュー (Azure キューなど) と、そのキューからの要求を処理する独立したバックエンド (Azure ワーカー ロールなど) が必要です。その後、MVC コントローラーはリクエストをキューに追加して返すことができます。その後、フロントエンドは完了をポーリングするか、SignalR などを介して通知を受け取ることができます。

于 2013-12-05T14:14:02.877 に答える