4

私は一日中この問題を整理しており、誰かが私の問題を特定するのを手伝ってくれることを願っています. ajax を使用して、アプリに「非同期プログレス コールバック」タイプの機能を作成しました。機能を取り除いてテスト アプリケーションに入れると、目的の結果が得られます。下の画像を参照してください。

望ましい機能 ここに画像の説明を入力

同じコードを使用して機能を単一ページ アプリケーションに結び付けると、最後のタスクが完了した後にのみすべての要求が応答されるという一種のブロッキングの問題が発生します。上記のテスト アプリでは、すべてのリクエストが順番に応答されます。サーバーは、コントローラーのメソッドが完了するまで、すべての要求について (「保留中」) 状態を報告します。何が動作の変化を引き起こす可能性があるかについて、誰かが私にヒントを与えることができますか?

望ましくない ここに画像の説明を入力

望ましい Fiddler 要求/応答

GET http://localhost:12028/task/status?_=1383333945335 HTTP/1.1
X-ProgressBar-TaskId: 892183768
Accept: */*
X-Requested-With: XMLHttpRequest
Referer: http://localhost:12028/
Accept-Language: en-US
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)
Connection: Keep-Alive
DNT: 1
Host: localhost:12028

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Vary: Accept-Encoding
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcUHJvamVjdHNcVEVNUFxQcm9ncmVzc0Jhclx0YXNrXHN0YXR1cw==?=
X-Powered-By: ASP.NET
Date: Fri, 01 Nov 2013 21:39:08 GMT
Content-Length: 25

Iteration completed...

望ましくない Fiddler 要求/応答

GET http://localhost:60171/_Test/status?_=1383341766884 HTTP/1.1
X-ProgressBar-TaskId: 838217998
Accept: */*
X-Requested-With: XMLHttpRequest
Referer: http://localhost:60171/Report/Index
Accept-Language: en-US
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)
Connection: Keep-Alive
DNT: 1
Host: localhost:60171
Pragma: no-cache
Cookie: ASP.NET_SessionId=rjli2jb0wyjrgxjqjsicdhdi; AspxAutoDetectCookieSupport=1; TTREPORTS_1_0=CC2A501EF499F9F...; __RequestVerificationToken=6klOoK6lSXR51zCVaDNhuaF6Blual0l8_JH1QTW9W6L-3LroNbyi6WvN6qiqv-PjqpCy7oEmNnAd9s0UONASmBQhUu8aechFYq7EXKzu7WSybObivq46djrE1lvkm6hNXgeLNLYmV0ORmGJeLWDyvA2


HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Vary: Accept-Encoding
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcUHJvamVjdHNcSUxlYXJuLlJlcG9ydHMuV2ViXHRydW5rXElMZWFybi5SZXBvcnRzLldlYlxfVGVzdFxzdGF0dXM=?=
X-Powered-By: ASP.NET
Date: Fri, 01 Nov 2013 21:37:48 GMT
Content-Length: 25

Iteration completed...

認証トークン以外の 2 つの要求ヘッダーの唯一の違いは、要求の " Pragma: no-cache " と応答の asp.net バージョンです。

ありがとう

更新 - 投稿されたコード(おそらく、このコードが Dino Espositoの記事に由来するものであることを示す必要があります)

var ilProgressWorker = function () {
    var that = {};
    that._xhr = null;
    that._taskId = 0;
    that._timerId = 0;
    that._progressUrl = "";
    that._abortUrl = "";
    that._interval = 500;
    that._userDefinedProgressCallback = null;
    that._taskCompletedCallback = null;
    that._taskAbortedCallback = null;
    that.createTaskId = function () {
        var _minNumber = 100,
            _maxNumber = 1000000000;
        return _minNumber + Math.floor(Math.random() * _maxNumber);
    };

    // Set progress callback
    that.callback = function (userCallback, completedCallback, abortedCallback) {
        that._userDefinedProgressCallback = userCallback;
        that._taskCompletedCallback = completedCallback;
        that._taskAbortedCallback = abortedCallback;
        return this;
    };

    // Set frequency of refresh
    that.setInterval = function (interval) {
        that._interval = interval;
        return this;
    };

    // Abort the operation
    that.abort = function () {
        //        if (_xhr !== null)
        //            _xhr.abort();
        if (that._abortUrl != null && that._abortUrl != "") {
            $.ajax({
                url: that._abortUrl,
                cache: false,
                headers: { 'X-ProgressBar-TaskId': that._taskId }
            });
        }
    };

    // INTERNAL FUNCTION
    that._internalProgressCallback = function () {
        that._timerId = window.setTimeout(that._internalProgressCallback, that._interval);
        $.ajax({
            url: that._progressUrl,
            cache: false,
            headers: { 'X-ProgressBar-TaskId': that._taskId },
            success: function (status) {
                if (that._userDefinedProgressCallback != null)
                    that._userDefinedProgressCallback(status);
            },
            complete: function (data) {
                var i=0;
            },
        });
    };

    // Invoke the URL and monitor its progress
    that.start = function (url, progressUrl, abortUrl) {
        that._taskId = that.createTaskId();
        that._progressUrl = progressUrl;
        that._abortUrl = abortUrl;

        // Place the Ajax call
        _xhr = $.ajax({
            url: url,
            cache: false,
            headers: { 'X-ProgressBar-TaskId': that._taskId },
            complete: function () {
                if (_xhr.status != 0) return;
                if (that._taskAbortedCallback != null)
                    that._taskAbortedCallback();
                that.end();
            },
            success: function (data) {
                if (that._taskCompletedCallback != null)
                    that._taskCompletedCallback(data);
                that.end();
            }
        });

        // Start the progress callback (if any)
        if (that._userDefinedProgressCallback == null || that._progressUrl === "")
            return this;
        that._timerId = window.setTimeout(that._internalProgressCallback, that._interval);
    };

    // Finalize the task
    that.end = function () {
        that._taskId = 0;
        window.clearTimeout(that._timerId);
    }

    return that;
};

更新 1 - John Saundersに感謝します。シリアル化されたアクセスに関するコメントでジョンが何を暗示しているかを説明しているこの記事を見つけることができました

" ASP.NET セッション状態へのアクセスはセッションごとに排他的であるため、並列実行をブロックし、並列要求を次々と強制的に実行させます"

4

1 に答える 1

1

私はついに修正を見つけました。セッション状態は、コントローラおよび/またはコントローラ メソッド レベルで制御できます。承認はより高いレベルで検証されているため、私が行っていることでセッションを使用する必要はありません。作業単位に対して無効にするだけです。

 [SessionState(SessionStateBehavior.Disabled)]
 public class _TestController : ProgressWorkerController
于 2013-11-02T16:46:08.233 に答える