ADO.NET2.0增加了一些新的特性,其中就包括異步查詢。這個特點在需要執行多個查詢的時候,或者查詢過程比較常的時候就很有用。而默認情況下是不開啓異步查詢的,必須要在連接字符串中顯示的打開,如下圖,圖中劃線的就是需要顯示制定的,後面一個是顯示的打開MARS。
下面的代碼包括了異步查詢的三種方法,所以代碼都可以測試運行,數據庫是NorthWind.
其中一個運行頁面如圖:
首先是頁面源碼:
<div>
<asp:GridView ID="GridView1" runat="server" BackColor="White" BorderColor="#CCCCCC"
BorderStyle="None" BorderWidth="1px" CellPadding="3">
<FooterStyle BackColor="White" ForeColor="#000066" />
<RowStyle ForeColor="#000066" />
<SelectedRowStyle BackColor="#669999" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="White" ForeColor="#000066" HorizontalAlign="Left" />
<HeaderStyle BackColor="#006699" Font-Bold="True" ForeColor="White" />
</asp:GridView>
</div>
<asp:GridView ID="GridView2" runat="server" BackColor="White" BorderColor="#336666"
BorderStyle="Double" BorderWidth="3px" CellPadding="4" GridLines="Horizontal">
<FooterStyle BackColor="White" ForeColor="#333333" />
<RowStyle BackColor="White" ForeColor="#333333" />
<SelectedRowStyle BackColor="#339966" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#336666" ForeColor="White" HorizontalAlign="Center" />
<HeaderStyle BackColor="#336666" Font-Bold="True" ForeColor="White" />
</asp:GridView>
</form>
後臺代碼:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindData();
//BindMultiData();
//BindMultiDataArray();
//BindDataWithCallBack();
}
}
//異步查詢的poll方式,最普通的方式
private void BindData()
{
string QueryStr = "SELECT * FROM customers";
using (SqlConnection Con = new SqlConnection(ConStr))
{
SqlCommand Cmd = new SqlCommand(QueryStr, Con);
IAsyncResult ASynResult;
SqlDataReader Da;
try
{
Con.Open();
//begin方法返回一個IAsyncResult對象,用來檢查執行是否完成
ASynResult = Cmd.BeginExecuteReader(CommandBehavior.CloseConnection);
while (!ASynResult.IsCompleted)
{
Response.Write("異步查詢</br>");
ASynResult.AsyncWaitHandle.WaitOne(3000, true);
//System.Threading.Thread.Sleep(10);
}
Da = Cmd.EndExecuteReader(ASynResult);
GridView1.DataSource = Da;
GridView1.DataBind();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}
}
//異步查詢的wait方式,使用多個等待句柄來異步查詢,必須等待所有進程完成處理結果集
private void BindMultiData()
{
string CusQueryStr = "SELECT * FROM customers WHERE CompanyName = 'Alfreds Futterkiste'";
string SupQueryStr = "SELECT Customers.CompanyName, Customers.ContactName, " +
"Orders.OrderID, Orders.OrderDate, " +
"Orders.RequiredDate, Orders.ShippedDate " +
"FROM Orders, Customers " +
"WHERE Orders.CustomerID = Customers.CustomerID " +
"AND Customers.CompanyName = 'Alfreds Futterkiste' " +
"ORDER BY Customers.CompanyName, Customers.ContactName";
using (SqlConnection MyCon = new SqlConnection(ConStr))
{
SqlCommand CusCmd = new SqlCommand(CusQueryStr, MyCon);
SqlCommand SupCmd = new SqlCommand(SupQueryStr, MyCon);
SqlDataReader CusDr;
SqlDataReader SupDr;
IAsyncResult CusIsynResult;
IAsyncResult SupIsynResult;
//創建句柄數組
System.Threading.WaitHandle[] WHandles = new System.Threading.WaitHandle[2];
System.Threading.WaitHandle CusHandle;
System.Threading.WaitHandle SupHandle;
MyCon.Open();
CusIsynResult = CusCmd.BeginExecuteReader(CommandBehavior.CloseConnection);
SupIsynResult = SupCmd.BeginExecuteReader(CommandBehavior.CloseConnection);
CusHandle = CusIsynResult.AsyncWaitHandle;
SupHandle = SupIsynResult.AsyncWaitHandle;
//將等待句柄賦給句柄數組
WHandles[0] = CusHandle;
WHandles[1] = SupHandle;
//將數組傳給waitall方法,等待所以的異步查詢完成
System.Threading.WaitHandle.WaitAll(WHandles);
CusDr = CusCmd.EndExecuteReader(CusIsynResult);
SupDr = SupCmd.EndExecuteReader(SupIsynResult);
GridView1.DataSource = CusDr;
GridView1.DataBind();
GridView2.DataSource = SupDr;
GridView2.DataBind();
MyCon.Dispose();
CusCmd.Dispose();
SupCmd.Dispose();
}
}
//採用WaitAny方式,優點是不用等待所有進程都完成才處理結果集
private void BindMultiDataArray()
{
string CusQueryStr = "SELECT * FROM customers WHERE CompanyName = 'Alfreds Futterkiste'";
string SupQueryStr = "SELECT Customers.CompanyName, Customers.ContactName, " +
"Orders.OrderID, Orders.OrderDate, " +
"Orders.RequiredDate, Orders.ShippedDate " +
"FROM Orders, Customers " +
"WHERE Orders.CustomerID = Customers.CustomerID " +
"AND Customers.CompanyName = 'Alfreds Futterkiste' " +
"ORDER BY Customers.CompanyName, Customers.ContactName";
using (SqlConnection MyCon = new SqlConnection(ConStr))
{
SqlCommand CusCmd = new SqlCommand(CusQueryStr, MyCon);
SqlCommand SupCmd = new SqlCommand(SupQueryStr, MyCon);
SqlDataReader CusDr;
SqlDataReader SupDr;
IAsyncResult CusIsynResult;
IAsyncResult SupIsynResult;
System.Threading.WaitHandle[] WHandles = new System.Threading.WaitHandle[2];
System.Threading.WaitHandle CusHandle;
System.Threading.WaitHandle SupHandle;
int WHindex;
MyCon.Open();
CusIsynResult = CusCmd.BeginExecuteReader(CommandBehavior.CloseConnection);
SupIsynResult = SupCmd.BeginExecuteReader(CommandBehavior.CloseConnection);
CusHandle = CusIsynResult.AsyncWaitHandle;
SupHandle = SupIsynResult.AsyncWaitHandle;
WHandles[0] = CusHandle;
WHandles[1] = SupHandle;
for (int i = 0; i < WHandles.Length; i++)
{
//waitany好處在於不必等待所有異步操作完成
WHindex = System.Threading.WaitHandle.WaitAny(WHandles);
switch (WHindex)
{
case 0:
CusDr = CusCmd.EndExecuteReader(CusIsynResult);
GridView1.DataSource = CusDr;
GridView1.DataBind();
break;
case 1:
SupDr = SupCmd.EndExecuteReader(SupIsynResult);
GridView2.DataSource = SupDr;
GridView2.DataBind();
break;
}
}
MyCon.Dispose();
CusCmd.Dispose();
SupCmd.Dispose();
}
}
//通過回調來實現異步查詢
private void BindDataWithCallBack()
{
string SupQueryStr = "SELECT Customers.CompanyName, Customers.ContactName, " +
"Orders.OrderID, Orders.OrderDate, " +
"Orders.RequiredDate, Orders.ShippedDate " +
"FROM Orders, Customers " +
"WHERE Orders.CustomerID = Customers.CustomerID " +
"AND Customers.CompanyName = 'Alfreds Futterkiste' " +
"ORDER BY Customers.CompanyName, Customers.ContactName";
using (SqlConnection MyCon = new SqlConnection(ConStr))
{
SqlCommand SupCmd = new SqlCommand(SupQueryStr, MyCon);
SqlDataReader SupDr;
IAsyncResult SupIsynResult;
MyCon.Open();
AsyncCallback Callback = new AsyncCallback(CallBackMethod);
SupIsynResult = SupCmd.BeginExecuteReader(Callback, SupCmd,CommandBehavior.CloseConnection);
System.Threading.Thread.Sleep(100);
MyCon.Dispose();
SupCmd.Dispose();
}
}
//回調方法
public void CallBackMethod(IAsyncResult IResult)
{
SqlCommand Command = (SqlCommand)IResult.AsyncState;
SqlDataReader dr = Command.EndExecuteReader(IResult);
GridView1.DataSource = dr;
GridView1.DataBind();
}
}