對上一次的做一點修改,增加一個比較美觀的進度顯示
0%20&&%20image.height>0){if(image.width>=510){this.width=510;this.height=image.height*510/image.width;}}"%20border=0>%20
上面那個是運行中的畫面,下面那個是結束后的畫面%20
0%20&&%20image.height>0){if(image.width>=510){this.width=510;this.height=image.height*510/image.width;}}"%20border=0>%20
用到的圖標在這里:
0%20&&%20image.height>0){if(image.width>=510){this.width=510;this.height=image.height*510/image.width;}}"%20border=0>%20
對上次的前臺修改如下:%20
<%@%20page%20language="c#"%20codebehind="webform54.aspx.cs"%20autoeventwireup="false"%20inherits="csdn.webform54"%20%>%20
<!doctype%20html%20public%20"-//w3c//dtd%20html%204.0%20transitional//en"%20>%20
<html>%20
<head>%20
<title>webform54</title>%20
<meta%20content="microsoft%20visual%20studio%20.net%207.1"%20name="generator">%20
<meta%20content="c#"%20name="code_language">%20
<meta%20content="javascript"%20name="vs_defaultclientscript">%20
<meta%20content="http://schemas.microsoft.com/intellisense/ie5"%20name="vs_targetschema">%20
<style%20type="text/css">%20
.font%20{%20font-weight:%20normal;%20font-size:%209pt;%20color:%20#000000;%20font-family:%20"宋體",%20sans-serif;%20background-color:%20#f0f0f0;%20text-decoration:%20none%20}%20
</style>%20
</head>%20
<body>%20
<form%20id="form1"%20method="post"%20runat="server">%20
<div%20id="div_load"%20runat="server">%20
<table%20width="320"%20height="72"%20border="1"%20bordercolor="#cccccc"%20cellpadding="5"%20cellspacing="1"%20
class="font"%20>%20
<tr>%20
<td>%20
<p><img%20alt="請等待"%20src="http://www.pushad.com/info/clocks.gif" align="left">
<br>
<asp:label id="lab_state" runat="server"></asp:label></p>
</td>
</tr>
</table>
<br>
</div>
<asp:button id="btn_startwork" runat="server" text="運行一個長時間的任務"></asp:button><br>
<br>
<asp:label id="lab_jg" runat="server"></asp:label>
</form>
</body>
</html>
后臺修改如下:
using system;
using system.collections;
using system.componentmodel;
using system.data;
using system.data.sqlclient;
using system.drawing;
using system.web;
using system.web.sessionstate;
using system.web.ui;
using system.web.ui.webcontrols;
using system.web.ui.htmlcontrols; namespace csdn
{
/// <summary>
/// webform54 的摘要說明。
/// </summary>
public class webform54 : system.web.ui.page
{
protected system.web.ui.htmlcontrols.htmlgenericcontrol div_load;
protected system.web.ui.webcontrols.button btn_startwork;
protected system.web.ui.webcontrols.label lab_state;
protected system.web.ui.webcontrols.label lab_jg;
protected work w;
private void page_load(object sender, system.eventargs e)
{
// 在此處放置用戶代碼以初始化頁面
if(session["work"]==null)
{
w=new work();
session["work"]=w;
}
else
{
w=(work)session["work"];
}
switch(w.state)
{
case 0:
{
this.div_load.visible=false;
break;
}
case 1:
{
this.lab_state.text=""+((timespan)(datetime.now-w.starttime)).totalseconds.tostring("0.00")+" 秒過去了,完成百分比:"+w.percent+" %";
this.btn_startwork.enabled=false;
page.registerstartupscript("","<script>window.settimeout('location.href=location.href',1000);</script>");
this.lab_jg.text="";
break;
}
case 2:
{
this.lab_jg.text="任務結束,并且成功執行所有操作,用時 "+((timespan)(w.finishtime-w.starttime)).totalseconds+" 秒";
this.btn_startwork.enabled=true;
this.div_load.visible=false;
break;
}
case 3:
{
this.lab_jg.text="任務結束,在"+((timespan)(w.errortime-w.starttime)).totalseconds+"秒的時候發生錯誤導致任務失敗'";
this.btn_startwork.enabled=true;
this.div_load.visible=false;
break;
}
}
}
#region web 窗體設計器生成的代碼
override protected void oninit(eventargs e)
{
//
// codegen: 該調用是 asp.net web 窗體設計器所必需的。
//
initializecomponent();
base.oninit(e);
}
/// <summary>
/// 設計器支持所需的方法 - 不要使用代碼編輯器修改
/// 此方法的內容。
/// </summary>
private void initializecomponent()
{
this.btn_startwork.click += new system.eventhandler(this.btn_startwork_click);
this.load += new system.eventhandler(this.page_load);
}
#endregion
private void btn_startwork_click(object sender, system.eventargs e)
{
if(w.state!=1)
{
this.btn_startwork.enabled=false;
this.div_load.visible=true;
w.runwork();
page.registerstartupscript("","<script>location.href=location.href;</script>");
}
}
}
public class work
{
public int state=0;//0-沒有開始,1-正在運行,2-成功結束,3-失敗結束
public int percent=0;//完成百分比
public datetime starttime;
public datetime finishtime;
public datetime errortime;
public void runwork()
{
lock(this)
{
if(state!=1)
{
state=1;
starttime=datetime.now;
system.threading.thread thread=new system.threading.thread(new system.threading.threadstart(dowork));
thread.start();
}
}
}
private void dowork()
{
try
{
sqlconnection conn=new sqlconnection(system.configuration.configurationsettings.appsettings["conn"]);
sqlcommand cmd=new sqlcommand("insert into test (test)values('test')",conn);
conn.open();
for(int p=0;p<100;p++)
{
for(int i=0;i<10;i++)
{
cmd.executenonquery();
}
percent=p;//這里就是定義百分比,你估計這個操作費多少時間定義多少百分比
}
conn.close();
//以上代碼執行一個比較消耗時間的數據庫操作
state=2;
}
catch
{
errortime=datetime.now;
percent=0;
state=3;
}
finally
{
finishtime=datetime.now;
percent=0;
}
}
}
}
在asp.net中執行一個長時間的操作,有的時候需要在在客戶端有一個反饋能了解到任務的執行進度,大致看了一下有這么幾種做法:
(1)按下按鈕的時候給出一個<div>提示正在執行任務,執行完畢讓這個<div>隱藏
(2)按下按鈕的時候跳轉到一個提示任務正在執行的頁面,執行完畢了再跳轉回來
(3)做一個任務類,開啟另外一個線程執行任務,同時在客戶端或者服務器端保存這個類的實例來跟蹤任務的執行情況
(1)和(2)的情況用的比較多,也比較簡單,缺點是不能實時的知道任務的執行進度,而且時間一長可能會超時,(3)的方法就會比較好的解決上面說的2個缺點。下面著重說一下(3)的實現方法,先從簡單開始,我們做一個任務類,在客戶端時時(暫且刷新時間為1秒)得知任務執行了多少時間,并且在成功完成任務后給出執行時間,在任務出錯的時候給出出錯的時間。
前臺
<form id="form1" method="post" runat="server">
<asp:label id="lab_state" runat="server"></asp:label><br>
<asp:button id="btn_startwork" runat="server" text="運行一個長時間的任務"></asp:button>
</form>
后臺
先是一些類的申明:
protected system.web.ui.webcontrols.button btn_startwork;
protected system.web.ui.webcontrols.label lab_state;
//前面2個是vs.net自己生成的
protected work w;
在page_load里面輸入以下代碼:
if(session["work"]==null)
{
w=new work();
session["work"]=w;
}
else
{
w=(work)session["work"];
}
switch(w.state)
{
case 0:
{
this.lab_state.text="還沒有開始任務";
break;
}
case 1:
{
this.lab_state.text="任務進行了"+((timespan)(datetime.now-w.starttime)).totalseconds+"秒";
this.btn_startwork.enabled=false;
page.registerstartupscript("","<script>window.settimeout(’location.href=location.href’,1000);</script>");
//不斷的刷新本頁面,隨時更新任務的狀態
break;
}
case 2:
{
this.lab_state.text="任務結束,并且成功執行所有操作,用時"+((timespan)(w.finishtime-w.starttime)).totalseconds+"秒";
this.btn_startwork.enabled=true;
break;
}
case 3:
{
this.lab_state.text="任務結束,在"+((timespan)(w.errortime-w.starttime)).totalseconds+"秒的時候發生錯誤導致任務失敗";
this.btn_startwork.enabled=true;
break;
}
}
在按鈕單擊事件內輸入以下代碼:
if(w.state!=1)
{
this.btn_startwork.enabled=false;
w.runwork();
page.registerstartupscript("","<script>location.href=location.href;</script>");
//立即刷新頁面
}
另外建立一個任務類,代碼如下:
public class work
{
public int state=0;//0-沒有開始,1-正在運行,2-成功結束,3-失敗結束
public datetime starttime;
public datetime finishtime;
public datetime errortime;
public void runwork()
{
lock(this)//確保臨界區被一個thread所占用
{
if(state!=1)
{
state=1;
starttime=datetime.now;
system.threading.thread thread=new system.threading.thread(new system.threading.threadstart(dowork));
thread.start();
}
}
}
private void dowork()
{
try
{
sqlconnection conn=new sqlconnection(system.configuration.configurationsettings.appsettings["conn"]);
sqlcommand cmd=new sqlcommand("insert into test (test)values(’test’)",conn);
conn.open();
for(int i=0;i<5000;i++)cmd.executenonquery();
conn.close();
//以上代碼執行一個比較消耗時間的數據庫操作
state=2;
}
catch
{
errortime=datetime.now;
state=3;
}
finally
{
finishtime=datetime.now;
}
}
}
}
運行這個頁面,看到每秒頁面刷新一次反饋任務執行到現在的時間,在結束后給出任務總的用時。(如果任務出錯也給出出錯時間)
(這個示例比較簡單,基本能實現長時間的任務執行與客戶端的交互,但是界面不是很友善,而且如果有很多項操作的話,只能給出執行了多少時間,不能顯示執行到第幾項任務,在下一篇文章中,將會改進這個類和界面)