• ADO.NET的新功能:MARS(Multiple Active Result Set) 及 异步执行命令


    在 2.0 以前的版本中 , 通常为每个数据库服务器的请求打开和关闭一个连接 ,  并且同时只能执行一条命令 , 也就是不支持异步进程 , 打开数据库服务器的连接是一个很消耗资源的操作 , 如果能重用连接并且支持异步进程将会很爽... 现在 2.0 中的 MARS 及对异步进程的支持可以实现这件事情....
    MARS(Multiple Active Result Set) 多动结果集是 ADO.NET 提供的一个新功能 , MARS 可以在同一连接上处理多个活动的结果集 ,  因为重用了连接 , 减少了数据库的访问 , 从而大大的提高了性能 . 这个功能结合另一新功能 : 对异步进程的支持 是一个很强大的功能~~~
    需要注意的是 : 使用 ADO.NET 2.0 的异步进程 ,  数据库连接字符串要添加 Asynchronous Processing=true 如果执行多条命令连接字符串还要添加 MultipleActiveResultSets=true , 否则会抛出异常 : 此连接不支持 MultipleActiveResultSets。
    这里使用的数据库及表为  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( );
                }
            }
            
    //System.Threading.WaitHandle.WaitAll( wailtHandles );
            
    //SqlDataReader sqlReaderCustomer = sqlCmdCustomer.EndExecuteReader( asyncResultCustomer );
            
    //GridView1.DataSource = sqlReaderCustomer;
            
    //GridView1.DataBind( );
            
    //SqlDataReader sqlReaderOrder = sqlCmdOrder.EndExecuteReader( asyncResultOrder );
            
    //GridView2.DataSource = sqlReaderOrder;
            
    //GridView2.DataBind( );
        }
    注意这里的数据库连接字符串加上了 MultipleActiveResultSets=true  , 还有点是这个功能目前只支持 MS SQL SERVER 2005 及以上版本
    如果要取消异步进程 ,  则只需在调用相应的 Command 对象的 Cancel 方法 , 如果想要 Rollback 已由 Command 对象完成的处理 , 则在执行命令前提供一个定制事务 .
    可以看出 MARS 和异步命令处理一起使用是很强大的~


  • 相关阅读:
    按位与、或、非、异或总结
    Linux 挂载命令
    Linux 文件系统常用命令
    Linux 系统命令sudo权限
    Linux 文件系统属性chattr权限
    Linux 文件特殊权限-Sticky BIT
    Linux 文件特殊权限-SetGID
    Linux 文件特殊权限-SetUID
    Linux 递归acl权限和默认acl权限
    Linux 最大有效权限与删除ACL
  • 原文地址:https://www.cnblogs.com/blackman/p/2045207.html
Copyright © 2020-2023  润新知