4

我整天都在整理这个问题,希望有人能帮助找出我的问题。我使用 ajax 在我的应用程序中创建了一个“异步进度回调”类型的功能。当我将功能剥离到测试应用程序中时,我得到了想要的结果。见下图:

所需的功能 在此处输入图像描述

当我使用相同的代码将功能绑定到我的单页应用程序中时,我遇到了一种阻塞问题,即只有在最后一个任务完成后才响应所有请求。在上面的测试应用程序中,所有请求都按顺序响应。服务器报告所有请求的(“挂起”)状态,直到控制器方法完成。谁能给我一个提示,说明什么可能导致行为改变?

不想要 在此处输入图像描述

所需的提琴手请求/响应

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...

不想要的提琴手请求/响应

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...

除了身份验证令牌之外,两个请求标头的唯一区别是请求中的“ 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 回答