zoukankan      html  css  js  c++  java
  • ASP.NET 多线程 监控任务执行情况,并显示进度条

    关于多线程的基本概念和知识在本文中不多讲,而且我懂的也不是很透,说的太多误人子弟...对于我来说,做本文提到的功能够用就行,等实现其他效果不够用的时候,再深入研究

    推荐看园子里的两篇博客应该就有个基本的认识了:

    C#多线程(一):http://www.cnblogs.com/oshyn/p/3628686.html

    C#多线程(二):http://www.cnblogs.com/oshyn/p/3628792.html

    有时候我们在执行一个较长任务的时候,浏览器就好比处于“挂起”的状态,你得等待他把这一个事情处理完毕再去处理其他事情。

    那么比如说我们在执行一个反复插入数据库的操作,或者说执行大量的IO的操作的时候,这个过程往往是很耗时的,浏览器长时间不响应,对于客户的忍耐度是一个挑战。

    就好像你在安装游戏,只有一段文字提示你“正在安装,请稍后...”结果稍后了半个小时还在稍后,我不知道还要稍后多久,那我简直要疯了。

    所以这时候,如果能实时显示当前安装包正在做什么,复制什么文件,执行什么操作,已完成了多少,还剩下多少。这样的话,果然是极好的......

    以前也知道做这个功能的时候需要用到多线程来执行,基本道理和思路也懂,但是觉得多线程太麻烦,也不利于管理,因此很傻很天真地想了一个变相解决方案。

    基本想法是这样的:

    在执行任务的页面上放上两段JS代码,分别是: dowork()  checkstate()。其中,dowork() 以ajax方式提交请求,执行耗时长的操作,在操作过程中,不断把执行信息写入Session,而checkstate()以ajax的方式提交请求,执行获取session信息,接收到响应之后,写入div中显示出来。

    然而事实上是,在执行操作过程中,确实把任务信息写入了session,但是在dowork()请求的任务执行完毕之前,checkstate()请求的 读取session的操作是不会执行的,在dowork请求的任务执行完毕之后,checkstate()才会把最终的session值获取到。

    虽然知道可能是关于单线程的任务执行顺序问题,但是具体说不出来个门道(有哪位行家给分析分析。。。。。不胜感谢~)

    后来就只能做多线程来实现了,不多废话,直接上代码,注释写的都很详细

    主要分为两个页面 一个任务执行页面(Default) ,放置的按钮和信息呈现的容器,另一个页面是ajax请求页面(ajaxWork),用来执行请求操作和返回响应信息。

    1 <div>
    2     多线程监测任务执行情况示例
    3     <br /><br />
    4     <div class="msg"><div class="msg2"></div></div><br />
    5    <input type="button" onclick="create('');" value="开始执行" />&nbsp;&nbsp;&nbsp;&nbsp;
    6    <span></span>
    7     </div>
    Default.aspx
     1 function create(value) //写一个点击执行的函数,点击请求时,实参为空
     2     {
     3         var url="ajaxwork.aspx"; //初始化请求地址
     4         
     5         if(value!="") //判断如果实参不为空,则带参请求
     6         {
     7             url+="?key="+value
     8         }
     9         
    10         $.post(url,function(data)
    11         {
    12             var rs = new Function("return" + data)(); //转换JSON数据
    13             
    14             $("span").html("用时:"+rs.time+"&nbsp;&nbsp;&nbsp;&nbsp;已完成:"+rs.curr+"%"); //输出当前任务执行情况
    15             
    16             $(".msg2").css("width",rs.curr+"%"); // 控制进度条的加载
    17             
    18             if(rs.curr!="100") //判断如果没有查到100 则递归执行本方法
    19             {
    20                 create("1"); //带参请求(参数是多少无所谓,有就行),获取任务执行状态
    21             }
    22         });
    23     } 
    页面脚本
     1 using System;
     2 using System.Threading;
     3 
     4 public partial class AjaxWork : System.Web.UI.Page
     5 {
     6     static string count = "";
     7     protected void Page_Load(object sender, EventArgs e)
     8     {
     9         if (Request.QueryString["key"] == null) //判断如果为空 则为第一次请求 启动所要执行的任务
    10         {
    11             Start();
    12         }
    13         else //否则为请求任务执行的状态
    14         {
    15             ajaxResponse();
    16         }
    17     }
    18 
    19     /// <summary>
    20     /// 线程所要执行的查数方法
    21     /// </summary>
    22     private void DoWork()
    23     {
    24         count = "{'curr':'0','time':'00:00:00.0000000'}";//每次执行操作之前 初始化信息
    25         DateTime starttime = DateTime.Now; //获取任务开始的时间
    26         for (int i = 1; i < 101; i++) //从1查数到100
    27         {
    28             Thread.Sleep(100); // 为了不让程序一下执行完毕,设置线程的休眠,方便演示
    29             count = "{'curr':'" + i.ToString() + "','time':'" +(DateTime.Now - starttime) + "'}"; //反馈当前任务状态
    30         }
    31     }
    32 
    33     /// <summary>
    34     /// 线程启动
    35     /// </summary>
    36     private void Start()
    37     {
    38         Thread t = new Thread(DoWork); //实例化一个线程
    39         t.Start(); //启动
    40         Response.Write("{'curr':'0','time':'00:00:00.0000000'}"); //第一次请求返回初始化的信息
    41     }
    42 
    43     /// <summary>
    44     /// 获取任务的实时信息
    45     /// </summary>
    46     private void ajaxResponse()
    47     {
    48         Response.Write(count);
    49         Response.Flush();
    50         Response.End();
    51     }
    52 }
    ajaxWork.aspx.cs

    效果如下图:

    Demo下载:http://files.cnblogs.com/webconfig/Thread.rar 

    ==============================华丽的分割线==================================

    另外一个问题是,不知道为什么,在ajaxWork.aspx.cs中 声明的

     1 static string count = "" 

    如果你在每次执行线程的时候不进行初始化操作

    那么,你在第一次执行的时候,是正常的。但是,第一次执行完成之后,再次点按钮的时候,就会出现“抽筋”情况,具体可以下载demo看效果、

    断电调试,可以发现,第二次执行,count初始化的值,不是“”,而是第一次执行完毕之后的值:

    哪位高手给解释一下...

    忽然想到了生命周期的问题,原来一直以为,静态变量的生命周期是随着类的消亡而消亡的,对于ASP.NET,好像不是这样,看到一篇文章上提到,静态变量是application级别的,也就是说除非IIS重启,否则静态变量的值就是最后修改的值...也许可以解释这个问题吧

    文章地址:http://www.cnblogs.com/webconfig/p/3632260.html

    ---- 内容补充 -------------------------------------------------------------------------------

    今天下午有稍微研究了一下,也感谢@AllEmpty提出的观点,用静态变量传值确实会引发并发问题,当时为了图省事直接用静态变量传值了。后来想过用session传值,可是在新开辟的线程中使用session 总是引发异常,异常提示为:

    今天下午终于找到原因了,那就是在新开辟的线程使用session之前,需要在主线程中声明出session,否则就会引起该异常。

    所以我们修改代码:

    1,声明的静态变量count去掉,在线程启动之前在主线程声明出session

            if (Request.QueryString["key"] == null) //判断如果为空 则为第一次请求 启动所要执行的任务
            {
                Session["count"] = "";
                Start();
            }


    2,使用session记录状态:

     1     private void DoWork()
     2     {
     3         Session["count"] = "{'curr':'0','time':'00:00:00.0000000'}";//每次执行操作之前 初始化信息
     4         DateTime starttime = DateTime.Now; //获取任务开始的时间
     5         for (int i = 1; i < 101; i++) //从1查数到100
     6         {
     7             Thread.Sleep(100); // 为了不让程序一下执行完毕,设置线程的休眠,方便演示
     8             Session["count"] = "{'curr':'" + i.ToString() + "','time':'" + (DateTime.Now - starttime) + "'}"; //反馈当前任务状态
     9         }
    10     }


    3,响应session的值

    1         string countstr = "";
    2         if (Session["count"] != null)
    3         {
    4             countstr = Session["count"].ToString();
    5         }
    6         Response.Write(countstr);

    OK,并发问题解决!!!

    本文出自博客园:D调的码农

    转载请注明出处:http://www.cnblogs.com/webconfig/p/3632208.html

  • 相关阅读:
    codeforces 980A Links and Pearls
    zoj 3640 Help Me Escape
    sgu 495 Kids and Prizes
    poj 3071 Football
    hdu 3853 LOOPS
    hdu 4035 Maze
    hdu 4405 Aeroplane chess
    poj 2096 Collecting Bugs
    scu 4444 Travel
    zoj 3870 Team Formation
  • 原文地址:https://www.cnblogs.com/webconfig/p/3632208.html
Copyright © 2011-2022 走看看