一般來說在進行SQL 資料查詢的動作難免會遇到需要耗費大量時間
這種狀況通常在Web Form中我們比較不容易注意到
但是在使用必須有即時性的應用程式介面中則是一定會碰到的
一般來說在進行SQL 資料查詢的動作難免會遇到需要耗費大量時間
這種狀況通常在Web Form中我們比較不容易注意到
但是在使用必須有即時性的應用程式介面中則是一定會碰到的
好在SQL Server2005可以支援非同步操作資料庫
SQL Server要進行非同步的作業其實很簡單
重點全在於sqlcommand的操作
string _asyncConn = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;
SqlConnection _conn = new SqlConnection(_asyncConn);
_conn.Open();
SqlCommand _cmd = _conn.CreateCommand();
_cmd.CommandText = "waitfor delay '00:00:05' SELECT top 100 * FROM Orders o";
_cmd.BeginExecuteReader(new AsyncCallback(delegate(IAsyncResult iar)
{
DataTable _table = new DataTable("Orders");
_table.Load(_cmd.EndExecuteReader(iar));
dataGridView1.Invoke(new Action(delegate()
{
dataGridView1.DataSource = _table;
}));
}), null);
_cmd.Dispose();
_conn.Close();
_conn.Dispose();
connection這樣設定
<add name="NorthwindConnectionString"
connectionString="Data Source=XXX;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=XX;async=true;"
providerName="System.Data.SqlClient" />
這邊為了看到效果所以先使用了waitfor的語法等待5秒鐘
另外有一個需要注意的地方是我並沒有把使用using來包sqlconnection
原因是因為在Asynchronous作業中我需要使用AsyncCallback來處理當Asynchronous完成後要做的事
但是包在using時我猜測
using(){
} <==
到右大跨號時會將裡面產生的物件釋放
而Asynchronous本來就會另外開一條Thread去處理其他工作
所以如果我將_cmd包在using中的話
在程式執行到_cmd.BeginExecuteReader(new AsyncCallback(delegate(IAsyncResult iar)此行時就另外建立一條Thread並繼續執行下去
然後到}及釋放裡面的資源(連Asynchronous中的AsyncCallback等也都被釋放掉)
我想另外寫一份測試程式
string _asyncConn = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;
using (SqlConnection _conn = new SqlConnection(_asyncConn))
{
_conn.Open();
SqlCommand _cmd = _conn.CreateCommand();
_cmd.CommandText = "waitfor delay '00:00:05' SELECT top 100 * FROM Orders o";
_cmd.BeginExecuteReader(new AsyncCallback(delegate(IAsyncResult iar)
{
DataTable _table = new DataTable("Orders");
_table.Load(_cmd.EndExecuteReader(iar));
dataGridView1.Invoke(new Action(delegate()
{
dataGridView1.DataSource = _table;
}));
}), null);
}
MessageBox.Show(DateTime.Now.ToString());
以及剛剛的測試在最後也加上一段同樣的MessageBox.Show…
可以發現程式是不等待Asynchronous的
反推回來所以放在using中的Asynchronous
會永遠等不到結果Orz…
這點需要注意。