C# 異步查詢數據庫(第二版)


  此文是接着我上篇文章寫的,我在上篇文章中講了異步查詢數據庫的方法,但例子寫的有些草率,我只寫了一次查詢,沒能表現出異步方式無阻塞的優點,因此根據園友的反映,我又對原來的代碼做了些修改,增加普通和異步兩種方式對數據庫的查詢操作的示例,希望對大家有所幫助。

  主要代碼如下:

1         /// <summary>
2 /// 當點擊執行查詢時發生
3 /// </summary>
4 private void Button_DoSearch_Click(object sender, EventArgs e)
5 {
6 Application.DoEvents();
7 DoSearchAsync();
8 //DoSearchNormal();
9 }

 

 1         /// <summary>
2 /// 異步方式查詢Customers和Orders
3 /// </summary>
4 private void DoSearchAsync()
5 {
6 this.Text = "異步方式查詢數據庫";
7 GetAllOrders();
8 GetAllCustomers();
9 }
10
11 /// <summary>
12 /// 普通方式查詢Customers和Orders
13 /// </summary>
14 private void DoSearchNormal()
15 {
16 this.Text = "普通方式查詢數據庫";
17 mWatch.Start();
18 GetAllCustomersNormal();
19 GetAllOrdersNormal();
20 mWatch.Stop();
21 label_Time.Text = "查詢耗時:" + mWatch.ElapsedMilliseconds.ToString() + "毫秒";
22 }

 

View Code
  1 /// <summary>
2 /// 普通方式查詢orders
3 /// </summary>
4 private void GetAllOrdersNormal()
5 {
6 try
7 {
8 mConnection = new SqlConnection(mConnectionString);
9 string sqlString = "select * from Orders";
10 SqlCommand command = new SqlCommand(sqlString, mConnection);
11 mConnection.Open();
12 SqlDataReader reader = command.ExecuteReader();
13 DataTable dataTable = new DataTable();
14 dataTable.Load(reader);
15 dgv_Data.DataSource = dataTable;
16 }
17 catch (Exception ex)
18 {
19 label_Time.Text = ex.Message;
20 }
21 finally
22 {
23 if (mConnection != null)
24 {
25 mConnection.Close();
26 }
27 }
28 }
29
30 /// <summary>
31 /// 普通方式查詢Customers
32 /// </summary>
33 private void GetAllCustomersNormal()
34 {
35 try
36 {
37 mConnection2 = new SqlConnection(mConnectionString);
38 string sqlString = "select * from Customers";
39 SqlCommand command = new SqlCommand(sqlString, mConnection2);
40 mConnection2.Open();
41 SqlDataReader reader = command.ExecuteReader();
42 DataTable dataTable = new DataTable();
43 dataTable.Load(reader);
44 dgv_Customer.DataSource = dataTable;
45 }
46 catch (Exception ex)
47 {
48 label_Time2.Text = ex.Message;
49 }
50 finally
51 {
52 if (mConnection2 != null)
53 {
54 mConnection2.Close();
55 }
56 }
57 }
58
59 /// <summary>
60 /// 異步方式查詢orders
61 /// </summary>
62 private void GetAllOrders()
63 {
64 mConnection = new SqlConnection(mConnectionString);
65 string sqlString = "select * from Orders";
66 SqlCommand command = new SqlCommand(sqlString, mConnection);
67 mConnection.Open();
68 mWatch.Start();
69 AsyncCallback callBack = new AsyncCallback(HandleCallback);//注冊回調方法
70 //開始執行異步查詢,將Command作為參數傳遞到回調函數以便執行End操作
71 command.BeginExecuteReader(callBack, command);
72 }
73
74 /// <summary>
75 /// 異步方式查詢customers
76 /// </summary>
77 private void GetAllCustomers()
78 {
79 mConnection2 = new SqlConnection(mConnectionString);
80 string sqlString = "select * from Customers";
81 SqlCommand command = new SqlCommand(sqlString, mConnection2);
82 mConnection2.Open();
83 mCustomerWatch.Start();
84 AsyncCallback callBack = new AsyncCallback(HandleCustomerCallback);
85 command.BeginExecuteReader(callBack, command);
86 }
87
88 /// <summary>
89 /// 異步查詢orders的回調方法
90 /// </summary>
91 /// <param name="MyResult">異步操作狀態</param>
92 private void HandleCallback(IAsyncResult MyResult)
93 {
94 try
95 {
96 SqlCommand command = (SqlCommand)MyResult.AsyncState;
97 SqlDataReader reader = command.EndExecuteReader(MyResult);
98 mWatch.Stop();
99 string callBackTime = mWatch.ElapsedMilliseconds.ToString() + "毫秒";
100 DataTable dataTable = new DataTable();
101 dataTable.Load(reader);
102 this.Invoke(myTimeDelegate, callBackTime);
103 this.Invoke(myDataDelegate, dataTable);
104 }
105 catch (Exception MyEx)
106 {
107 this.Invoke(new DisplayInfoDelegate(DisplayTimeResults), String.Format(MyEx.Message));
108 }
109 finally
110 {
111 if (mConnection != null)
112 {
113 mConnection.Close();
114 }
115 }
116 }
117
118 /// <summary>
119 /// 異步查詢customers的回調方法
120 /// </summary>
121 /// <param name="MyResult">異步操作狀態</param>
122 private void HandleCustomerCallback(IAsyncResult MyResult)
123 {
124 try
125 {
126 SqlCommand command = (SqlCommand)MyResult.AsyncState;
127 SqlDataReader reader = command.EndExecuteReader(MyResult);
128 mCustomerWatch.Stop();
129 string callBackTime = mCustomerWatch.ElapsedMilliseconds.ToString() + "毫秒";
130 DataTable dataTable = new DataTable();
131 dataTable.Load(reader);
132 this.Invoke(myCustomerTimeDelegate, callBackTime);
133 this.Invoke(myCustomerDelegate, dataTable);
134 }
135 catch (Exception MyEx)
136 {
137 this.Invoke(new DisplayInfoDelegate(DisplayTimeResults), String.Format(MyEx.Message));
138 }
139 finally
140 {
141 if (mConnection2 != null)
142 {
143 mConnection2.Close();
144 }
145 }
146 }

普通方式查詢結果如圖1所示:

                  圖1

異步方式查詢結果如圖2所示:

                  圖2

  通過這兩張圖的對比,我們發現普通方式查詢耗時是304毫秒,異步方式兩張表的耗時加起來還不到10毫秒,速度差別是很明顯的。因為普通方式執行查詢的操作同在主線程上,兩次操作需要排隊,上一個操作未完成就會阻塞線程,這時程序是不能做任何事情的。而異步恰巧可以解決這個問題,兩次查詢操作都通過回調函數完成查詢,程序不會阻塞或掛起線程。

  其實,異步操作並沒有實質上提高查詢數據庫的速度,只是發揮了並行的長處。當操作大量的數據時,對數據庫的優化是必須的,建立索引,多使用存儲過程對提高查詢速度都有很大幫助。不得不說的是,異步確實還是有風險的,確定有必要使用時再用。

      本文例子可以到這里下載:http://files.cnblogs.com/yanchenglong/%E5%BC%82%E6%AD%A5%E6%96%B9%E5%BC%8F%E6%9F%A5%E8%AF%A2%E6%95%B0%E6%8D%AE%E5%BA%93.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM