asp.net页面中并行命令的执行

在asp.net中虽然可以使用异步命令,但是不应盲目使用。来看两种异步命令的使用场景。第一个场景是多条SQL语句的并行执行,可以面向单台数据库服务器,也可以是多台。


假设有个页面要显示某个客户的个人信息以及会计信息。前一部分来自客户端数据库,而后一部分则来自会计数据库,我们可以同时发起两个查询,使他们在两台计算机上并行执行,从而真正地利用并行机制。

  protected void btnQuery_Click(object sender, EventArgs e)
        {
            string custID = CustomerList.SelectedValue;

            using (SqlConnection conn1 = new SqlConnection())
            using (SqlConnection conn2 = new SqlConnection())
            {
                //开启第一个查询
                SqlCommand cmd1 = new SqlCommand(CustomerInfoCmd, conn1);
                cmd1.Parameters.Add("@customerid", SqlDbType.Char, 5).Value = custID;
                conn1.Open();
                IAsyncResult arCustomerInfo = cmd1.BeginExecuteReader();

                //开启第二个查询
                SqlCommand cmd2 = new SqlCommand(CustomerInfoCmd, conn2);
                cmd2.CommandType = CommandType.StoredProcedure;
                cmd2.Parameters.Add("@customerid", SqlDbType.Char, 5).Value = custID;
                conn2.Open();
                IAsyncResult arOrdersInfo = cmd2.BeginExecuteReader();

                //准备等待对象同步跟进
                WaitHandle[] handles = new WaitHandle[2];
                handles[0] = arCustomerInfo.AsyncWaitHandle;
                handles[1] = arOrdersInfo.AsyncWaitHandle;
                SqlDataReader reader;

                //等到所有命令终止(5秒以内)
                for (int i = 0; i < 2; i++)
                {
                    StringBuilder builder = new StringBuilder();
                    int index = WaitHandle.WaitAny(handles, 5000, false);
                    if (index == WaitHandle.WaitTimeout)
                    {
                        throw new Exception("超时!!!");
                    }
                    if (index == 0)//客户信息
                    {
                        reader = cmd1.EndExecuteReader(arCustomerInfo);
                        if (!reader.Read())
                        {
                            continue;
                        }
                        builder.AppendFormat("{0}<br>", reader["companyname"]);
                        builder.AppendFormat("{0}<br>", reader["adress"]);
                        builder.AppendFormat("{0}<br>", reader["country"]);
                        info.Text = builder.ToString();
                        reader.Close();
                    }
                    if (index==1)//订单信息
                    {
                        reader = cmd2.EndExecuteReader(arOrdersInfo);
                        gridOrders.DataSource = reader;
                        gridOrders.DataBind();
                        reader.Close();
                    }
                }
            }
        }

该页面同时发起了两个命令,然后等待第一个命令终止。两个IAsyncResult的AsyncWaitHandle对象存储在一个数组中,并传到了WaitHandle类的WaitAny方法中。若其中任意一个终止,WaitAny便会发出通知,外围的for语句会重复这种等待,直到所有挂起的命令都终止。选择WaitAll 方法更简单一些。在这种情况下,我们可以在所有结果集都就绪时进行处理。用WaitAny能够带来性能的提升,尤其对于那些高耗时的存储过程。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章