下面就是采用静态变量的方法实现的: 
 复制代码 代码如下:   <%@ Page Language="C#" %>  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1 -transitional.dtd">  <script runat="server">  private static int Processbar = 0;  private static int TotalCount = 100; //设置初始值,防止出现被0除。  protected void ProcessTask()  {  //通过计算,得出TotalCount的值,比如查询数据库等  TotalCount = 150;  while (Processbar < TotalCount)  {  Processbar += 5;  System.Threading.Thread.Sleep(1000);  }  } 
  protected void Page_Load(object sender, EventArgs e)  {  if (Request.QueryString["step"] != null && Request.QueryString["step"].Equals(String.Empty) == false)  {  if (Request.QueryString["step"].Equals("1"))  {  Processbar = 0;  System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(ProcessTask));  thread.Start();  Response.ClearContent();  Response.Write(0);  Response.End();  }  else  {  Response.ClearContent();  if (Processbar < TotalCount)  {  Response.Write(Processbar * 100 / TotalCount);  }  else  {  Response.Write("ok");  }  Response.End();  }  }  }  </script> 
  <html xmlns="http://www.w3.org/1999/xhtml ">  <head runat="server">  <title>在客户端显示服务器端任务处理进度条的探讨</title>  <script type="text/javascript">  var http = null;  var count = 1;  var timer = null;  function createXMLHTTP() {  return window.XMLHttpRequest ? new window.XMLHttpRequest() : new window.ActiveXObject("MSXML2.XMLHTTP");  }  function showProcess() {  http = createXMLHTTP()  http.open("GET", "<%=Request.Url.ToString() %>?step=" + (count++) + "&" + Date.parse(new Date()), true);  http.onreadystatechange = function() {  if (http.readyState == 4 && http.status == 200)  if ("ok" == http.responseText) {  document.getElementById("process").innerHTML = "完成";  window.clearInterval(timer);  }  else {  document.getElementById("process").innerHTML = http.responseText + "%";  }  }  http.send(null);  } 
  function startTask() {  count = 1;  document.getElementById("process").innerHTML = "0%";  timer = window.setInterval("showProcess()", 1000);  return false;  }  </script> 
  </head>  <body>  <form runat="server">  <input type="button" value="开始处理长时间操作" />  <div></div>  </form>  </body>  </html> 
    这种方法,在一个用户访问的情况下是没有问题的,但多个用户访问时就会造成混乱。 
  下面这这种方法,是常用的方法,一般情况下可以满足需求: 
 复制代码 代码如下:   <%@ Page Language="C#" %> 
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1 - 
  transitional.dtd"> 
  <script runat="server">  /// <summary>  /// 设置全局变量,以便不同的方法是用  /// </summary>  private int Processbar = 0; //设置初始的状态,也可以代表一系列步骤中的每个步骤。  private int TotalCount = 100; //设置初始值,防止出现被0除。  private String key;  protected void ProcessTask()  {  while (Processbar < TotalCount)  {  Processbar = this.GetProcessbar() + 5; //这里只是模拟一下,每次加 5  System.Threading.Thread.Sleep(1000); //这里只是模拟一个长时间的执行过程。  SaveData();  }  } 
  protected void Page_Load(object sender, EventArgs e)  {  key = Request.QueryString["guid"]; //多个并发请求时,用来区分客户端的请求。  if (String.IsNullOrEmpty(key)) key = Guid.NewGuid().ToString();  Processbar = this.GetProcessbar();  TotalCount = this.GetTotalCount(); 
  //以下判断原来判断请求的不同过程,是第一次请求,还是更新进度条的请求,实现方法也可以划分为多个程序来实现。  if (Request.QueryString["step"] != null && Request.QueryString["step"].Equals(String.Empty) == false)  {  if (Request.QueryString["step"].Equals("1"))  {  // 开始执行任务的请求,启动长时间的任务处理。  Processbar = 0;  //通过计算,得出TotalCount的值,比如查询数据库等,也可以是一个任务的多个步骤的总和。  TotalCount = 200; //假如完成一个任务需要200个步骤  SaveData();  System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(ProcessTask));  thread.Start();  Response.ClearContent();  Response.Write(0);  Response.End();  }  else  {  Response.ClearContent();  if (Processbar < TotalCount)  {  // 输出处理的过程  Response.Write(Processbar * 100 / TotalCount);  }  else  {  // 所有的任务都完成了,输出结束信息,终止前端的请求。  Response.Write("ok");  Cache.Remove(key);  }  Response.End();  }  }  else  {  G.Text = key;  if (System.IO.File.Exists(Server.MapPath(key + ".txt")))  {  System.IO.File.Delete(Server.MapPath(key + ".txt"));  }  }  } 
  /// <summary>  /// 得到执行过程的阶段  /// </summary>  /// <returns></returns>  private int GetProcessbar()  {  String data = Convert.ToString(Cache.Get(key));  if (String.IsNullOrEmpty(data))  return 0;  else  {  return Convert.ToInt32(data.Split(',')[0]);  }  } 
  /// <summary>  /// 得到全部的过程数  /// </summary>  /// <returns></returns>  private int GetTotalCount()  {  String data = Convert.ToString(Cache.Get(key));  if (String.IsNullOrEmpty(data))  return 0;  else  {  return Convert.ToInt32(data.Split(',')[1]);  }  } 
  /// <summary>  /// 将过程保存。  /// </summary>  private void SaveData()  {  WriteLog();  Cache.Insert(key, Processbar.ToString() + "," + TotalCount.ToString());  } 
  private void WriteLog()  {  System.IO.StreamWriter sw = new System.IO.StreamWriter(Server.MapPath(key + ".txt"), true);  sw.WriteLine("Processbar = " + Processbar + " TotalCount = " + TotalCount + " " + System.DateTime.Now.ToString 
  ());  sw.Close();  }  </script> 
  <html xmlns="http://www.w3.org/1999/xhtml ">  <head runat="server">  <title>在客户端显示服务器端任务处理进度条的探讨</title> 
  <script type="text/javascript">  var http = null;  var count = 1;  var timer = null;  var guid = "<asp:Literal runat='server'/>";  function createXMLHTTP() {  return window.XMLHttpRequest ? new window.XMLHttpRequest() : new window.ActiveXObject("MSXML2.XMLHTTP");  }  function showProcess() {  http = createXMLHTTP();  http.open("GET", "<%=Request.Url.ToString() %>?step=" + (count++) + "&guid=" + guid + "&" + Date.parse(new 
  Date()), true);  http.setRequestHeader("Connection", "close");  http.onreadystatechange = function() {  if (http.readyState == 4 && http.status == 200)  if ("ok" == http.responseText) {  document.getElementById("process").innerHTML = document.getElementById("processbar1").innerHTML = "完成";  document.getElementById("processbar2").style.width = "100%";  window.clearInterval(timer);  }  else {  document.getElementById("process").innerHTML = document.getElementById("processbar1").innerHTML = 
  http.responseText + "%";  document.getElementById("processbar2").style.width = http.responseText + "%";  }  }  http.send(null);  } 
  function startTask() {  count = 1;  document.getElementById("process").innerHTML = document.getElementById("processbar1").innerHTML = "0%";  document.getElementById("processbar2").style.width = "0%";  timer = window.setInterval("showProcess()", 1000);  return false;  }  </script> 
  </head>  <body>  <form runat="server">  <input type="button" value="启动处理长时间操作" />  <div>  <div></div>  <div></div>  </div>  <div></div>  </form>  </body>  </html> 
    代码执行效果:
     但是,这种方法就是万事大吉了吗?完全错误,这种方法仍然存在显示不准确的现象,造成显示不准确的原因就是 Cache 的使用,IIS 6之后,增加了应用程序池的功能,这个功能可以大大提高程序的性能,减少程序本身的错误导致的整个网站的崩溃。但是,如果应用程序池的“性能”-“Web 园”数目设置大于1的情况下,HttpApplicationState(Application)、Cache、HttpSessionState(Session)这些变量都是都是无法使用了,这是因为:每个Web 园会启动一个w3wp.exe工作进程,每个工作进程之间是相互独立的,以上这些变量也就是不是共享的了,所以,使用Cache保存程序执行进度的方法也是不完全正确的。 
  那么终极的方法是什么呢?对,将程序执行进度保存在第三方的存储介质上,如数据库,文件系统等等都是可以的。这个方法代码我就不写了,就是增加访问数据库的部分即可。                        (编辑:52站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |