浅谈利用ASP.NET多线程执行长时间的任务

在ASP.NET中执行一个长时间的操作,有的时候需要在在客户端有一个反馈能了解到任务的执行进度,大致看了一下有这么几种做法:

(1)按下按钮的时候给出一个<div>提示正在执行任务,执行完毕让这个<div>隐藏

(2)按下按钮的时候跳转到一个提示任务正在执行的页面,执行完毕了再跳转回来

(3)做一个任务类,开启另外一个线程执行任务,同时在客户端或者服务器端保存这个类的实例来跟踪任务的执行情况(1)和(2)的情况用的比较多,也比较简单,缺点是不能实时的知道任务的执行进度,而且时间一长可能会超时,(3)的方法就会比较好的解决上面说的2个缺点。下面着重说一下(3)的实现方法,先从简单开始,我们做一个任务类,在客户端时时(暂且刷新时间为1秒)得知任务执行了多少时间,并且在成功完成任务后给出执行时间,在任务出错的时候给出出错的时间。


ASP.NET多线程前台

 
 
  1. <form id="Form1" method="post" runat="server">   
  2. <asp:label id="lab_state" runat="server"></asp:label><br>   
  3. <asp:Button id="btn_startwork" runat="server" Text="运行一个长时间的任务"></asp:Button>   
  4. </form>  

ASP.NET多线程后台

先是一些类的申明: 

 
 
  1. protected System.Web.UI.WebControls.Button btn_startwork;   
  2. protected System.Web.UI.WebControls.Label lab_state;   
  3. //前面2个是vs.net自己生成的   
  4. protected work w;   
  5. 在Page_Load里面输入以下代码:   
  6. if(Session["work"]==null)   
  7.    {   
  8.     w=new work();   
  9.     Session["work"]=w;   
  10.    }   
  11.    else   
  12.    {   
  13.     w=(work)Session["work"];   
  14.    }   
  15.    switch(w.State)   
  16.    {   
  17.     case 0:   
  18.     {   
  19.      this.lab_state.Text="还没有开始任务";   
  20.      break;   
  21.     }   
  22.     case 1:   
  23.     {   
  24.      this.lab_state.Text="任务进行了"+((TimeSpan)(DateTime.Now-w.StartTime)).TotalSeconds+"秒";   
  25.      this.btn_startwork.Enabled=false;   
  26.      Page.RegisterStartupScript("","<script>window.setTimeout(’locationlocation.href=location.href’,1000);</script>");   
  27.      //不断的刷新本页面,随时更新任务的状态   
  28.      break;   
  29.     }   
  30.     case 2:   
  31.     {   
  32.      this.lab_state.Text="任务结束,并且成功执行所有操作,用时"+((TimeSpan)(w.FinishTime-w.StartTime)).TotalSeconds+"秒";   
  33.      this.btn_startwork.Enabled=true;   
  34.      break;   
  35.     }   
  36.     case 3:   
  37.     {   
  38.      this.lab_state.Text="任务结束,在"+((TimeSpan)(w.ErrorTime-w.StartTime)).TotalSeconds+"秒的时候发生错误导致任务失败";   
  39.      this.btn_startwork.Enabled=true;   
  40.      break;   
  41.     }   
  42.    }  

在按钮单击事件内输入以下代码:

 
 
  1. if(w.State!=1)   
  2.    {   
  3.     this.btn_startwork.Enabled=false;   
  4.     w.runwork();   
  5.     Page.RegisterStartupScript("","<script>locationlocation.href=location.href;</script>");   
  6.     //立即刷新页面   
  7.    }  

另外建立一个任务类,代码如下:

 
 
  1. public class work   
  2.  {   
  3.   public int State=0;//0-没有开始,1-正在运行,2-成功结束,3-失败结束   
  4.         public DateTime StartTime;   
  5.   public DateTime FinishTime;   
  6.   public DateTime ErrorTime;   
  7.   public void runwork()   
  8.   {   
  9.    lock(this)//确保临界区被一个Thread所占用   
  10.    {   
  11.     if(State!=1)   
  12.     {   
  13.      State=1;   
  14.      StartTime=DateTime.Now;   
  15.      System.Threading.Thread thread=new System.Threading.Thread(new System.Threading.ThreadStart(dowork));   
  16.      thread.Start();                            
  17.     }   
  18.    }   
  19.   }   
  20.   private void dowork()   
  21.   {   
  22.    try   
  23.    {   
  24.     SqlConnection conn=new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["conn"]);   
  25.     SqlCommand cmd=new SqlCommand("Insert Into test (test)values(’test’)",conn);   
  26.     conn.Open();   
  27.     for(int i=0;i<5000;i++)cmd.ExecuteNonQuery();   
  28.     conn.Close();   
  29.     //以上代码执行一个比较消耗时间的数据库操作   
  30.     State=2;   
  31.    }   
  32.    catch   
  33.    {   
  34.     ErrorTime=DateTime.Now;   
  35.     State=3;   
  36.    }   
  37.    finally   
  38.    {   
  39.     FinishTime=DateTime.Now;   
  40.    }   
  41.   }   
  42.  }   
  43. }  

运行这个页面,看到每秒页面刷新一次反馈任务执行到现在的时间,在结束后给出任务总的用时。(如果任务出错也给出出错时间)

(这个ASP.NET多线程示例比较简单,基本能实现长时间的任务执行与客户端的交互,但是界面不是很友善,而且如果有很多项操作的话,只能给出执行了多少时间,不能显示执行到第几项任务,在下一篇文章中,将会改进这个类和界面)


这个知识很有趣,很多地方都用到了,实现的基本思路都差不多,只不过显示页面有些变化而已。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值