| ??????? 某些場合下,在對數據庫進行訪問時,為了避免同步訪問數據時所帶來的延遲,我們需要改進設計,以提高程序執行效率。一方面,這可以給用戶以良好的使用體驗;另一方面,也降低了程序崩潰的可能性。為實現這一目的,我們采用異步方式來訪問數據庫。 ??????? 什么是異步呢?簡單來說,就是并行執行。它與同步是相對立的,我們平時所有用到的方式大都屬于同步執行。比如,在一段程序中,標號為 B 的語句在標號為 A 的語句后面,那行,如果 A 語句沒有執行完,那么 B 語句就得不到執行。而異步則不同,我們可以把異步執行理解為輕型線程。當程序在 A 處開始異步執行的時候,主程序繼續執行,而異步語句中指定的操作則在后臺線程上與主線程同時執行。因此,它提高了程序執行的效率,也減少了阻塞的可能。 ??????? 實現異步的方法有多種,這里我們采用異步回調方式,使用異步回調時,我們需要實例化 AsyncCallback 委托,這是系統定義的委托。在 .NET 中,提供了一系列用于異步操作的方法。每種異步操作通常包含了兩個方法,即 BeginXXX() 和 EndXXX()。比如,我們下面即將要用到的 BeginExecuteReader() 和 EndExecuteReader()。 ??????? 請看代碼(本文采用 C# 語言): using System; using System.ComponentModel; using System.Data; using System.Text; using System.Data.SqlClient; using System.Drawing; using System.Windows.Forms; namespace 異步訪問數據庫 { //定義一個委托,這個委托在下面顯示數據時會用到,它接受一個 DataTable 類型的參數 ??? public delegate void ShowData(DataTable dt); ??? //窗體類 ??? public partial class UsingCallBack : Form ??? { ??????? DataSet ds = new DataSet(); ??????? ShowData sd; //定義委托變量 ??????? public UsingCallBack() ??????? { ??????????? InitializeComponent(); ??????????? this.StartPosition = FormStartPosition.CenterScreen; ??????? } ??????? private void UsingCallBack_Load(object sender, EventArgs e) ??????? { //為委托指定方法 ??????????? sd = new ShowData(this.ShowDataFunction); ??????? } ??????? private void button1_Click(object sender, EventArgs e) ??????? { ??????????? //定義異步回調委托 ??????????? AsyncCallback ac=new AsyncCallback(CallbackProcedure); ??????????? this.Text = "正在異步讀取數據庫,您可以執行其它操作..."; ??????????? //定義數據庫變量 ??????????? SqlConnectionStringBuilder cSB = new SqlConnectionStringBuilder(); ??????????? cSB.ConnectionString = "Server=.;Initial Catalog=Northwind;Integrated Security=True"; ???? //這一步是最關鍵的,用 AsynchronousProcessing 的屬性來指定是否可以執行異步操作 ??????????? cSB.AsynchronousProcessing = true; ??????????? SqlConnection sqlCon = new SqlConnection(cSB.ConnectionString); ??????????? string SQL = "Select * From Orders"; ??????????? SqlCommand sqlCmd = new SqlCommand(SQL, sqlCon); ??????????? sqlCon.Open(); //開始異步讀取 ??????????? sqlCmd.BeginExecuteReader(ac, sqlCmd); ????????????? ??????? } //異步回調過程,在異步操作完成時調用,故稱回調 ??????? public void CallbackProcedure(IAsyncResult ar) { ??????????? SqlDataReader sDR; ??????????? SqlCommand sqlCmd = (SqlCommand)ar.AsyncState; ??????????? sDR = sqlCmd.EndExecuteReader(ar); ??????????? ds.Load(sDR, LoadOption.OverwriteChanges, "Result"); //執行委托:這個委托我們在最上面已經定義過,它負責將執行結果顯示 ??????????? Invoke(sd, ds.Tables["Result"]);??????????? ??????? } ??????? public void ShowDataFunction(DataTable dt) { ???? //將 DataGridView 的 DataSouce 屬性值設為傳過來的 DataTable ??????????? this.DGV.DataSource =dt; ??????? } ??? } } ??????? 通過上述程序,我們可以看到,在異步訪問數據庫時,我們需要使用對象 SqlConnectionStringBuilder ,只有當該對象的 AsynchronousProcessing 屬性為 True 時,我們才能執行異步操作。 對于上述程序,如果您有不了解的地方或者改進意見,可以留言;如果需要全部源代碼,也可以留言。希望我們能共同交流。 |