標籤:
Web開發中使用多線程可以增強使用者體驗,尤其是多使用者、多任務、海量資料和資源緊張的情況下。所以我們的ASP.Net教程設立多線程編程實戰專題。下面這些代碼範例都是入門級的,希望對對大家學習ASP.Net多線程編程有所協助。
一 ASP.Net利用多線程執行長時間的任務
這裡以一個簡單的範例作為我們ASP.Net教程多線程編程實戰專題的開始。
在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;
}
}
}
}
運行這個頁面,看到每秒頁面重新整理一次反饋任務執行到現在的時間,在結束後給出任務總的用時。(如果任務出錯也給出出錯時間)
(這個樣本比較簡單,基本能實現長時間的任務執行與用戶端的互動,但是介面不是很友善,而且如果有很多項操作的話,只能給出執行了多少時間,不能顯示執行到第幾項任務,在下一篇文章<ASP.Net教程系列:多線程編程實戰(一) 續>http://www.cnblogs.com/elock/archive/2010/04/11/1709566.html中,將會改進這個類和介面)
ASP.Net教程系列:多線程編程實戰(一)