SQL Server的非同步做法

  • 3303
  • 0
  • C#
  • 2009-12-29

一般來說在進行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…

這點需要注意。