也就是說,畫面需要呈現目前進行到第幾筆,總共幾筆。
以下是我的實作。 實作分成兩部份,一個是伺服器端的同步,也就是一般的寫法。另一個則是伺服器端的非同步。
在 asp.net 的應用程式中,最怕的一種需求,莫過於大量資料匯入,客戶又要求以 Web form 來呈現,並要求匯入的進度。
也就是說,畫面需要呈現目前進行到第幾筆,總共幾筆。
以下是我的實作。 實作分成兩部份,一個是伺服器端的同步,也就是一般的寫法。另一個則是伺服器端的非同步。
aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" Async="true" AsyncTimeout="1" %>
Code Behind
using System;
using System.Web.Script.Services;
using System.Web.Services;
using System.Web.UI;
namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
private static SlowTask slowTask = null;
protected void Page_Load(object sender, EventArgs e)
{
}
[ScriptMethod]
[WebMethod]
public static string GetTaskCurrentProgress()
{
return string.Format("{0}/{1} : {2}", slowTask.CurrentCount, slowTask.TotalCount,
slowTask.GetAsyncTaskProgress());
}
public void RunItAsync()
{
slowTask = new SlowTask(1000);
PageAsyncTask asyncTask1 = new PageAsyncTask(slowTask.OnBegin, slowTask.OnEnd, null, "Async", true);
RegisterAsyncTask(asyncTask1);
}
[ScriptMethod]
[WebMethod]
public static void RunItSync()
{
slowTask = new SlowTask(1000);
slowTask.ExecuteAsyncTask();
}
protected void Button1_Click(object sender, EventArgs e)
{
RunItAsync();
Page.ClientScript.RegisterStartupScript(typeof(string), "ok", "");
}
}
}
關於 SlowTask 的程式如下,主要是封裝長時間工作的內容
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;
namespace WebApplication1
{
public class SlowTask
{
private readonly int totalCount;
public int TotalCount
{
get
{
return totalCount;
}
}
public SlowTask(int count)
{
totalCount = count;
}
private String taskGrogress;
private AsyncTaskDelegate dlgt;
protected delegate void AsyncTaskDelegate();
public String GetAsyncTaskProgress()
{
return taskGrogress;
}
public void ExecuteAsyncTask()
{
Random r = new Random(5);
for (int i = 0; i < totalCount; i++)
{
Thread.Sleep(10 * r.Next(5));
CurrentCount++;
}
}
public int CurrentCount { get; set; }
public IAsyncResult OnBegin(object sender, EventArgs e,
AsyncCallback cb, object extraData)
{
taskGrogress = "AsyncTask started at: " + DateTime.Now + ". ";
dlgt = new AsyncTaskDelegate(ExecuteAsyncTask);
IAsyncResult result = dlgt.BeginInvoke(cb, extraData);
return result;
}
public void OnEnd(IAsyncResult ar)
{
taskGrogress += "AsyncTask completed at: " + DateTime.Now;
dlgt.EndInvoke(ar);
}
public void OnTimeout(IAsyncResult ar)
{
taskGrogress += "AsyncTask failed to complete because it exceeded the AsyncTimeout parameter.";
}
}
}
畫面如下
AJAX 的部份,可參考 AJAX 之 PageMethod 。
由實驗得知,兩種實作起來,伺服器端同步的AJAX效果比較好,但伺服器端非同步的伺服器資源使用率會較高。
程式碼可由這裡下載
1 則留言:
本人對長時間的工作編排有些不明白。
原來使用者在按submit後是會增加一項資料,然後更新頁面
若果現在除此之外,要在加資料後,背後要把相關大量資料生成報表存入資料庫(可能要幾分鐘)
怎樣做才可以不影響更新頁面的時間,背後繼續運行呢?
我想到的就是用async的方法,但只有己概念而已。
究竟應該怎樣做呢?
張貼留言