首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > asp.net >

高手赐教B/S模式多线程例子,该如何处理

2011-12-31 
高手赐教B/S模式多线程例子这是我的代码,但是感觉没有缩短时间protected void Button3_Click(object sende

高手赐教B/S模式多线程例子
这是我的代码,但是感觉没有缩短时间
  protected void Button3_Click(object sender, EventArgs e)
  {
  Thread thread2 = new Thread(new ThreadStart(bind2));
  Thread thread1 = new Thread(new ThreadStart(bind1));
  thread1.Start();
  thread2.Start();
  // thread.Join(TimeSpan.FromSeconds(100));
  Thread.CurrentThread.Join(TimeSpan.FromSeconds(100));

  thread2.Abort();
  thread1.Abort();
  }
  protected void bind1()
  {
  string ids = this.txtID.Text.Trim(); //父类ID
  string str = this.DropDownList2.SelectedValue.Trim();
  if (str == "父级id值")
  {
  ids = this.txtID.Text.Trim();
  }
  else if (str == "class")
  {
  ids = "";
  }
  string xpath = this.txtXPath.Text.Trim();//抓取链接的xpath
  string url = this.txtUrl.Text.Trim();//网站的url

  string pagePath = "";
  string s = getstr(url, ids, pagePath, xpath);//获取结果值  
  this.txtLianJie.Text += s;
  }
  protected void bind2()
  {
  string ids = this.txtID.Text.Trim(); //父类ID
  string str = this.DropDownList2.SelectedValue.Trim();
  if (str == "父级id值")
  {
  ids = this.txtID.Text.Trim();
  }
  else if (str == "class")
  {
  ids = "";
  }
  string xpath = this.txtXPath.Text.Trim();//抓取链接的xpath
  string url = this.txtUrl.Text.Trim();//网站的url

  string pagePath = "";
  string s = getstr(url, ids, pagePath, xpath);//获取结果值  
  this.txtLianJie.Text += s;
  }

[解决办法]
顶:
创建了1个私有方法BindDataToRepeater用于把对应的SQL语句查询的结果绑定到对应的Repeater控件上。同时在此方法中使用了SqlDataReader,以提高绑定数据的速度。如果你使用了数据工厂可修改BindDataToRepeater中的具体实现过程;

  2个共有方法BindCategory和BindArchive分别用于创建不同SQL语句、设置Repater的ID;

  同时需要引入System.Web.UI、System.Web.UI.HtmlControls、System.Data.SqlClient3个必要的命名空间。

  值得注意的是在BindDataToRepeater方法中使用了try..catch语句,但并没有在catch块中做任何事情,为什么我们用try.catch却不在catch块中做点什么事情呢,不是多此一举吗?使用try..catch是为了防止在执行BindDataToRepeater时抛出异常,若此处出现异常且此方法是在多线程中执行的,将会导致IIS进程崩溃,进而影响其他页面的正常执行,故而用try...catch防止BindDataToRepeater抛出错误。

  我们之所以为数据绑定创建一个类,是为了提高内存利用率,当数据加载(Load)完毕的时候,为这个类创建的实例就会销毁。我们也可以通过在页面中创建几个全局变量来实现。但我还是建议以类的形式传递数据而不是使用全局变量。下面,我们开始在页面的Load中创建线程了。首先你需要在页面中引入System.Threading命名空间。

public classBindData
{
private int currentPage = 1;
private Repeater rpID;

  public BindData(Repeater rpID)
  {
    this.rpID = rpID;
  }

  public BindData(Repeater rpID,int page)
  {
    this.rpID = rpID;
    this.currentPage = page;
  }

  public void BindCategory()
  {
    string strSql="SELECT * FROM Category";
    this.BindDataToRepeater(strSql, this.rpID);
  }

  public void BindArchive()
  {
    string strSql = string.Format("SELECT * FROM Archives WHERE Page={0}",this.currentPage);
    this.BindDataToRepeater(strSql, this.rpID);
  }

  private void BindDataToRepeater(string strSql, Repeater rp)
  {
  if (rp == null) return;
  SqlConnection conn = new SqlConnection("data source=数据服务器地址;User ID=用户名;pwd=密码;Initial Catalog=数据库名");
  SqlCommand cmd = new SqlCommand(strSql, conn);
  SqlDataReader dtr;
    try
    {
      conn.Open();


      dtr = cmd.ExecuteReader();
      controlID.DataSource = rp;
      controlID.DataBind();
      if (!dtr.IsClosed)
      dtr.Close();
    }
    catch { }
    finally
    {
      cmd.Dispose();
      if (conn.State = ConnectionState.Open)
      conn.Close();
    }
  }
}
 


  上面的代码显示在!IsPostBack状态下绑定数据。利用Request.QueryString获取了当前页码,并创建了BindData的2个实例LoadArchives、LoadCategory,通过 Thread thArhives=new Thread(new ThreadStart(LoadArchives.BindArchive))为绑定Arhice创建线程,通过Thread thCategory = new Thread(new ThreadStart(LoadCategory.BindCategory))为绑定分类创建线程,同时调用Thread的Start方法使2个线程进入执行状态。最后,在Load的最下面用Thread的Join方法使创建的2个线程与页面加载同步。

  值得注意的是,Join方法是必须的,如果不使用,可能导致创建的线程还未把数据完全绑定到Repeater上,Load就已经执行完毕,若如此页面上将没有任何数据。同时调用Start的代码行应尽量早,调用Join的代码行都应尽量迟——尽量放在Page_Load代码段的末尾,这样才能达到多线程的目的,若你每调用一个Start马上调用Join,其实质和没有使用多线程的效果是一样的。Join在MSND上的解释是:在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻塞调用线程,直到某个线程终止为止。

  只要设置好ASPX页面Repeater的绑定项,数据就可成功加载了。上面仅仅展示了2个SQL语句的查询,如果你有10个或者更多的SQL查询,在Page_Load中创建10个线程,让他们异步执行,最后用Join同步到Load,是一个提高性能的不错方法。


[解决办法]
已在你另个帖子中回复

热点排行