同步和异步访问数据库

   我们都知道,某些场合下,在对数据库进行访问时,为了避免同步访问数据时所带来的延迟,我们需要改进设计,以提高程序执行效率。一方面,这可以给用户以良好的使用体验;另一方面,也降低了程序崩溃的可能性。为实现这一目的,我们采用异步方式来访问数据库。先看下面的代码

 

private   void  button2_Click( object  sender, EventArgs e) 
       
{   

       
using (SqlConnection cn = new SqlConnection(cnSettings.ConnectionString))//新建连接 
              
               cn.Open(); 
               
//新建命令 
               using (SqlCommand cmd = cn.CreateCommand()) 
               

                   cmd.CommandText 
= "WaitFor Delay '00:00:15' Select @@Version"
                   ver 
= (string)cmd.ExecuteScalar(); 
               }
 
           }
 
           label1.Text 
= ver;

}


     这个例子非常简单,这是同步的例子,:首先建立一个连接,打开连接后,创建一个SqlCommand,并设置命令,最后将执行后的值给到label控件.可以看到,整个例子都是在一个线程内进行的,并没有涉及到其他的线程,再看一下下面的例子.

 

private   void  button2_Click( object  sender, EventArgs e) 
       
{   
   
//新建联接 
           SqlConnection cn = new SqlConnection(cnSettings.ConnectionString); 
           cn.Open(); 
           
//新建命令 
           SqlCommand cmd = cn.CreateCommand(); 
           cmd.CommandText 
= "WaitFor Delay '00:00:15' Select @@Version"
           
//在另外一个线程运行reader,ProcessResult可以看做是另外一个线程 
           cmd.BeginExecuteReader(new AsyncCallback(ProcessResult), cmd);

}


可以看到,上面的代码就是异步读取数据库,实际上就是开启了另外的一个线程,下面为处理代码

 

public   void  ProcessResult(IAsyncResult ar) 
       

           SqlCommand cmd 
= (SqlCommand)ar.AsyncState; 
           
using (cmd.Connection) 
           

               
using (cmd) 
               

                   
string ver = null
                   SqlDataReader rdr 
= cmd.EndExecuteReader(ar); 
                   
if (rdr.Read()) 
                   

                       ver 
= (string)rdr[0]; 
                       label1.BeginInvoke(
new LabelHandler(UpdateLabel), ver); 
                   }
 
               }
 
           }
 
       }
 

下面是委托的代码

      

  // 声明一个委托代理 
        public   delegate   void  LabelHandler( string  text); 

       
public   void  UpdateLabel( string  text) 
       

           label1.Text 
= text; 
       }


  

     值得注意的是,在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误的做法,正确的做法是将工作线程中涉及更新界面的代码封装为一个方法,通过 Invoke 或者 BeginInvoke 去调用,两者的区别就是一个导致工作线程等待,而另外一个则不会。

转载于:https://www.cnblogs.com/chinazhousheng/archive/2008/07/13/1241686.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值