4

長時間実行される非同期タスク用に単純な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クリックハンドラーにpreventDefaultを追加すると、ポストバックは起動しませんが(duh)、すべてのajax呼び出しは機能するため、少なくともすべてのajaxコードは正常に機能します。サーバーコードを実行できるようにポストバックボタンを設定し、ajax呼び出しを開始できるようにクライアントクリックイベントを実行する方法はありますか?私はここで困惑していると思います、それ以来、ページが破壊されてリロードされるので、私はaspポストバックなしでこれをすべて行う必要がありますよね?

私はこれについてすべて間違っていると確信しています。すべてのポストバックを回避し、サービスにajax呼び出しを行って非同期作業を実行し、サービスの完了率をポーリングすることを考えて、これらすべてをサービスに移動しようとしましたが、サービスはページ非同期を実装していないため、「RegisterAsyncTask」はありません。 ()」。.aspxページでできるように呼び出します。

また、セッション状態を使用して、非同期タスクとajax呼び出しの間で行われたパーセントの値を伝達しようとしています。これが機能するかどうかはわかりませんが、実験してみようと思いました。失敗した場合は、バックグラウンドタスクとajax呼び出しの間でパーセントを伝達する方法が必要です。

非同期Webサービスを作成する方法や、Webサービスによって生成されたプロキシでBeginxxx呼び出しなどを使用する方法について多くのことを読みましたが、私と同じようなことをしようとして、単純なajax呼び出しを行う人々の投稿もたくさん見つかりました。 jQueryを介して、そして私が見つけることができることを考えると、運も本当の答えもありません。

では、.aspxページから、ページ非同期またはサービスのいずれかを使用して長時間実行タスクを開始し、タスクの実行時に単純なhtml5プログレスバーを更新するにはどうすればよいですか?それは簡単なようですが、そうではありません:\

4

2 に答える 2

2

基本的なポイントが1つだけ欠けています。あなたのajax呼び出しはポストバックを生き残ることはできません。

ボタンクリックで呼び出すことはできませんPROGRESS.startProgress()。その直後にページをポストバックする必要があるためです。ポストバックにより、ajax呼び出しが終了します。

プログレスバーを表示したい場合は、ポストバックを使用せずにajaxを使用してファイルもアップロードする必要があります。役立つuploadifyのようなプラグインがあります。

于 2012-10-15T05:20:28.697 に答える
0

多くの苦痛と苦痛の後、SignalRを使用するようにソリューションを完全に書き直しました。これにより、必要なすべてのコードが大幅に簡素化されます。WebフォームWebサイトでSignalRを使用して長時間実行タスクの単純なHTML5プログレスバーを実行する簡単な方法の詳細については、ダウンロード可能なミニマリストサンプルと実用的なオンラインデモを含む、このテーマに関する私のブログ投稿を参照してください。誰かがそれを助けてくれることを願っています。

于 2014-02-11T06:59:23.027 に答える