ADO.NET的异步执行命令

在 2.0 以前的版本中 , 通常为每个数据库服务器的请求打开和关闭一个连接 ,  并且同时只能执行一条命令 , 也就是不支持异步进程 。

使用 ADO.NET 2.0 的异步进程 ,  数据库连接字符串要添加 Asynchronous Processing=true

如果执行多条命令连接字符串还要添加 MultipleActiveResultSets=true

这里使用的数据库及表为  MS Sql Server 2000 的 NorthWind 的 Customers 表 和 Orders 表 ,  页面上只需拖放相应的GridView 控件。
先看看异步回调 , 这里只执行一条命令 :

 
  
string strSelectCmdOrders = @" SELECT TOP 5 C.CustomerID,CompanyName,ContactName,
                 OrderID,OrderDate,ShipCity
FROM Customers C ,Orders O WHERE C.CustomerID = O.CustomerID
ORDER BY CompanyName,ContactName
" ;
// 以此变量判断异步执行是否完成
bool isComplete = false ;

protected void Page_Load( object sender, EventArgs e)
{
if ( ! IsPostBack )
{
SqlConnection sqlCon
=
        new
SqlConnection
       (
@" Data Source=.;Initial Catalog=NorthWind;
        Integrated Security=True;Asynchronous Processing=true
" );
SqlCommand sqlCmdOrders
= new SqlCommand( strSelectCmdOrders , sqlCon );
sqlCon.Open( );
sqlCmdOrders.BeginExecuteReader(
new AsyncCallback( callBackOrders ) ,
        sqlCmdOrders , CommandBehavior.CloseConnection );
// 如果异步执行完成则结束该事件处理
while ( ! isComplete )
{
System.Threading.Thread.Sleep(
1 );
}
}
}

private void callBackOrders ( IAsyncResult asyncResult )
{
using ( SqlCommand sqlCmdOrders = asyncResult.AsyncState as SqlCommand )
{
using ( SqlDataReader sqlReader = sqlCmdOrders.EndExecuteReader( asyncResult ) )
{
GridViewOrders.DataSource
= sqlReader;
GridViewOrders.DataBind( );
isComplete
= true ;
}
}
}
注意 BeginExecuteReader 方法的第2个参数 , 该参数接收一个传递给回调方法的定制对象 , 在回调方法里可以通过 AsyncState 获取该对象
通过跟踪程序 结合使用 SQL SERVER 事件探察器发现在调用 BeginExecuteReader 方法时执行了 SQL 语句.
再来看看 MARS 和 异步处理的结合:
 
  
string strSelectCmdOrders = @" SELECT TOP 5 C.CustomerID,CompanyName,ContactName,
OrderID,OrderDate,ShipCity
FROM Customers C ,Orders O WHERE C.CustomerID = O.CustomerID
AND CompanyName = 'Alfreds Futterkiste'
ORDER BY CompanyName,ContactName
" ;
string strSelectCmdCustomers = " SELECT * FROM Customers WHERE CompanyName = 'Alfreds Futterkiste' " ;

protected void Page_Load( object sender, EventArgs e)
{
if ( ! IsPostBack )
{
using ( SqlConnection sqlCon =
        new
SqlConnection( @ " Data Source=.;Initial Catalog=NorthWind;Integrated Security=True;
          Asynchronous Processing=true;MultipleActiveResultSets=true
" ) )
{
sqlCon.Open( );

SqlCommand sqlCmdCustomer
= new SqlCommand( strSelectCmdCustomers , sqlCon );
IAsyncResult asyncResultCustomer
= sqlCmdCustomer.BeginExecuteReader( );

SqlCommand sqlCmdOrder
= new SqlCommand( strSelectCmdOrders , sqlCon );
IAsyncResult asyncResultOrder
= sqlCmdOrder.BeginExecuteReader( );

System.Threading.WaitHandle waitHandleCustomer
=
                asyncResultCustomer.AsyncWaitHandle;
System.Threading.WaitHandle waitHandleOrder
=
                asyncResultOrder.AsyncWaitHandle;
System.Threading.WaitHandle[] waitHandles
=
          
new System.Threading.WaitHandle[] { waitHandleCustomer , waitHandleOrder };

for ( int i = 0 ; i < waitHandles.Length ; i ++ )
{
switch ( System.Threading.WaitHandle.WaitAny( waitHandles ) )
{
case 0 :
SqlDataReader sqlReaderCustomer
=
                  sqlCmdCustomer.EndExecuteReader( asyncResultCustomer );
GridView1.DataSource
= sqlReaderCustomer;
GridView1.DataBind( );
break ;
case 1 :
SqlDataReader sqlReaderOrder
=
                  sqlCmdOrder.EndExecuteReader( asyncResultOrder );
GridView2.DataSource
= sqlReaderOrder;
GridView2.DataBind( );
break ;
}
}
sqlCmdCustomer.Dispose( );
sqlCmdOrder.Dispose( );
}
}

}

注意这里的数据库连接字符串加上了 MultipleActiveResultSets=true  , 还有点是这个功能目前只支持 MS SQL SERVER 2005 及以上版本
如果要取消异步进程 ,  则只需在调用相应的 Command 对象的 Cancel 方法 , 如果想要 Rollback 已由 Command 对象完成的处理 , 则在执行命令前提供一个定制事务 .
可以看出 MARS 和异步命令处理一起使用是很强大的~

修改了部分的原文:http://blog.csdn.net/web718/archive/2009/04/17/4086462.aspx

转载于:https://www.cnblogs.com/Scarface/archive/2011/03/28/1997772.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值