转:在 .NET 中实现异步回调访问数据库

在 .NET 中实现异步回调访问数据库

时间:2009-11-17 19:52来源:网络收集 作者:佚名 点击: 334 次 技术论坛
某些场合下,在对数据库进行访问时,为了避免同步访问数据时所带来的延迟,我们需要改进设计,以提高程序执行效率。一方面,这可以给用户以良好的使用体验;另一方面,也降低了程序崩溃的可能性。为实现这一目的,我们采用异步方式来访问数据库。 什么是异步

        某些场合下,在对数据库进行访问时,为了避免同步访问数据时所带来的延迟,我们需要改进设计,以提高程序执行效率。一方面,这可以给用户以良好的使用体验;另一方面,也降低了程序崩溃的可能性。为实现这一目的,我们采用异步方式来访问数据库。
        什么是异步呢?简单来说,就是并行执行。它与同步是相对立的,我们平时所有用到的方式大都属于同步执行。比如,在一段程序中,标号为 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 时,我们才能执行异步操作。
对于上述程序,如果您有不了解的地方或者改进意见,可以留言;如果需要全部源代码,也可以留言。希望我们能共同交流。

posted on 2011-08-31 17:10  荣京  阅读(471)  评论(0编辑  收藏  举报