小编典典

Asp.Net MVC和Ajax异步回调执行顺序

ajax

我整天都在整理此问题,希望有人能帮助您确定我的问题。我已经使用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...

除auth令牌外,两个请求标头的唯一区别是请求中的“ 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 Session状态的访问是每个会话互斥的


阅读 277

收藏
2020-07-26

共1个答案

小编典典

我终于找到了解决办法。可以在控制器和/或控制器方法级别上控制会话状态。由于正在对授权进行更高级别的验证,因此我在执行操作时无需使用会话。我只是将其禁用为工作单位。

 [SessionState(SessionStateBehavior.Disabled)]
 public class _TestController : ProgressWorkerController
2020-07-26