jquery - ASP.net 进度条在异步操作期间通过 jQuery ajax 更新

标签 jquery asp.net ajax asynchronous progress-bar

我正在尝试为长时间运行的异步任务设置一个简单的 html 进度条。问题是我试图触发回发来运行一些服务器代码,并同时执行客户端单击事件来启动 ajax 轮询,这会导致 ajax 调用中返回错误。这是我的 jQuery 和 html 代码:

<%@ Page Language="C#" AsyncTimeout="230" CodeFile="test.aspx.cs" Inherits="test" %>

<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <script>
        "use strict";
        var PROGRESS;
        $(document).ready(function () {
            $.ajaxSetup({
                type: "POST",
                contentType: "application/json",
                data: '{}',
                timeout: 10000,
                converters: {
                    "text json": function (data) {
                        var msg;
                        msg = $.parseJSON(data);
                        return msg.hasOwnProperty('d') ? msg.d : msg;
                    }
                }
            });
            PROGRESS = {
                done: false,
                startProgress: function () {
                    var _progress = this;
                    $.ajax({
                        url: 'test.aspx/getProgress',
                        timeout: 20000,
                        data: '{}',
                        dataType: "json",
                        success: function (data) {
                            var currProgress = data * 100;
                            $("#prog").value = currProgress;
                            if (currProgress > 99)
                                _progress.done = true;
                            else
                                setTimeout("PROGRESS.startProgress()", 5000);
                        },
                        error: function (jqXHR, textStatus, errorThrown) {
                            var s = textStatus == null ? "" : textStatus;
                            s += errorThrown == null ? "" : ", " + errorThrown;
                            alert(s);
                        }
                    });
                }
            };
            $("#body_DoUploadButton").on("click", function (event) {
                //event.preventDefault();
                PROGRESS.startProgress();
            });
        });
    </script>
</head>
<body>
    <asp:Button ID="DoUploadButton" Text="Import file" OnClick="UploadButton_Click" runat="server"></asp:Button>
    <progress id="prog" value="0" max="100"></progress>
</body>

这是我的代码隐藏:

public partial class test : System.Web.UI.Page
{
    delegate void AsyncTaskDelegate();
    AsyncTaskDelegate _dlgt;

    IAsyncResult OnBegin(object sender, EventArgs e, AsyncCallback cb, object extraData)
    {
        _dlgt = new AsyncTaskDelegate(DoImport);
        IAsyncResult result = _dlgt.BeginInvoke(cb, extraData);
        return result;
    }

    void OnEnd(IAsyncResult ar)
    {
        _dlgt.EndInvoke(ar);
    }

    void OnTimeout(IAsyncResult ar)
    {
        //do something
    }

    [WebMethod(EnableSession = true)]
    public static double getProgress()
    {
        if (HttpContext.Current.Session["pctDone"] == null)
            return 0.0;
        return (double)HttpContext.Current.Session["pctDone"];
    }

    protected void DoImport()
    {
        int i = 10;
        while (i-- > 0)
        {
            System.Threading.Thread.Sleep(5000); //fake some work
            Session["pctDone"] = i / 10.0;
        }
        Session["pctDone"] = 1.0;
    }

    protected void UploadButton_Click(object sender, EventArgs e)
    {
        Session["pctDone"] = 0.0;
        PageAsyncTask task = new PageAsyncTask(new BeginEventHandler(OnBegin), new EndEventHandler(OnEnd),
            new EndEventHandler(OnTimeout), null);
        RegisterAsyncTask(task);
        ExecuteRegisteredAsyncTasks();
    }

    protected void Page_Init(object sender, EventArgs e)
    {
        Server.ScriptTimeout = 240;
    }
}

显然,单击按钮时的回发会干扰 ajax 调用。如果我在 javascript clickhandler 中添加 PreventDefault,则回发永远不会触发(废话),但所有 ajax 调用都可以工作,因此至少所有 ajax 代码都可以正常工作。有没有办法让按钮既回发,以便我的服务器代码可以运行,并执行客户端单击事件,以便我可以启动 ajax 调用?我想我完蛋了,我需要在没有 asp 回发的情况下完成这一切,因为那时页面会被销毁并重新加载,对吗?

我确信我的做法是错误的。我尝试将所有这些转移到服务中,认为我将避免所有回发,只需对服务进行 ajax 调用来完成异步工作,并轮询服务以获取完成百分比,但服务不实现页面异步,因此没有“RegisterAsyncTask” ()”,就像在 .aspx 页面上一样进行调用。

我还尝试使用 session 状态来传达异步任务和 ajax 调用之间完成的百分比值,我不知道它是否有效,但我想我应该尝试一下。如果失败,我需要某种方式来传达后台任务和 ajax 调用之间的百分比。

我已经阅读了很多关于如何制作异步Web服务以及在Web服务生成的代理中使用Beginxxx调用等的内容,但我也发现了很多人试图做与我类似的事情的帖子,使得通过 jQuery 进行简单的 ajax 调用,但我没有运气,也没有找到真正的答案。

那么,如何从 .aspx 页面通过页面异步或服务启动长时间运行的任务,并在任务运行时更新简单的 html5 进度条?看起来很简单,但事实并非如此:\

最佳答案

你只遗漏了一个基本点。您的 ajax 调用将无法在回发后继续存在。

您无法在单击按钮时调用 PROGRESS.startProgress(),因为您希望页面在此之后立即回发。回发会导致您的 ajax 调用被终止。

如果您想显示进度条,则还必须使用 ajax 上传文件,而不是使用回发。有类似 uploadify 的插件这会有所帮助。

关于jquery - ASP.net 进度条在异步操作期间通过 jQuery ajax 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12886241/

相关文章:

ruby-on-rails - Ruby on Rails : Ajax to Refresh Partial Not Working

Javascript - 函数不会从另一个函数运行

javascript - 阻止 slick.js 打开链接 onclick next

asp.net - @ inside razor 语法是否称为运算符?

c# - 可以在 EF 代码第一次迁移种子方法中设置断点吗?

javascript - 将全局 onBeforeCall 监听器附加到除一个之外的所有 AJAX 调用

javascript - 为什么对 Jquery Ajax URL 进行双重编码

javascript - 需要能够暂停和恢复 SetTimeout

Jquery ajax休息服务调用: Typo Error Access is denied

c# - web farm环境开发注意事项