我正在嘗試爲長時間運行的異步任務設置一個簡單的html進度欄。問題是我試圖啓動回發來運行一些服務器代碼,並同時執行客戶端單擊事件來啓動ajax輪詢,這會導致ajax調用中返回錯誤。這裏是我的jQuery和HTML代碼:在異步操作期間通過jQuery ajax更新ASP.net進度條
<%@ 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;
}
}
Apparnetly當點擊按鈕與Ajax調用干擾的回傳。如果我在javascript clickhandler中添加preventDefault,則回發從不會觸發(duh),但所有ajax調用都可以工作,所以至少所有的ajax代碼都可以正常工作。有沒有辦法讓按鈕都回發,所以我的服務器代碼可以運行,並做一個客戶端點擊事件,所以我可以啓動ajax調用?我認爲我在這裏搞砸了,我需要這樣做,沒有asp回發,因爲那時頁面被銷燬並重新加載,對吧?
我敢肯定,我對這一切都是錯誤的。我試着將所有這些都轉移到了一個服務上,我想避免所有的回發,並且只對服務進行ajax調用來完成異步工作,並且調查服務的完成百分比,但服務不實現頁面異步,所以沒有「RegisterAsyncTask ()「可以在.aspx頁面上調用。
我也試圖使用會話狀態來傳達異步任務和ajax調用之間完成百分比的值,我不知道它是否可以工作,但我想我會做實驗。如果失敗,我需要一些方法來傳達後臺任務和ajax調用之間的百分比。
我讀過很多關於如何在Web服務生成的代理中製作異步web服務和使用Beginxxx調用等的問題,但我也發現很多人試圖做類似於我的事情,通過jQuery進行簡單的Ajax調用,沒有運氣,也沒有真正的答案,因爲我可以找到。
因此,從.aspx頁面開始,如何使用頁面異步或服務啓動長時間運行的任務,並在任務運行時更新簡單的html5進度欄?似乎這將是簡單的,但沒有:\
我明白了。以下是事件的基本順序。我堅持使用asp.net上傳控件來獲取文件。在上傳按鈕處理程序中,我關閉了異步導入任務,然後設置了一個隱藏字段來指示我的javascript開始輪詢。異步任務將整個文件吸入到MemoryStream中(我不上傳大文件)然後開始處理。當它工作時,它獲取,更新並存儲在會話數據中完成的百分比。在我的JavaScript中,如果設置了隱藏字段,它會通過ajax開始輪詢我的WebMethod。aspx文件來獲取當前從會話中完成的百分比。 –
您可以發佈解決方法的更新代碼嗎? @EricSassaman –