XCStudio

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

可以用3种不同的方式处理异步命令。一种方式是启动异步进程,再选择 IAsyncResult对象,看看进程何时完成。第二种方式是在开始异步进程时提供一个回调方法。这种方式可以并行执行其他任务。异步进程完成时,就触发回调方法进行清理,并通知程序的其他部分该异步进程已完成。第三种也是最好的方法就是把一个等待句柄关联到异步进程上,使用这种方式,可以启动需要的所有异步进程,等待全部或部分进程的完成,以便对它们进行相应的处理。

Poll方式

using System.Data;
using System.Data.SqlClient;
using SYstem.Configuration;

public class SampleClass  
{  
    protocted void Page_Load(object sender,EventArgs e)  
    {  
        SqlConnection DBCon;  
        SqlCommand Command = new SqlCommand();  
        SqlDataAdapter OrderReader;  
        IAsyncResult AsyncResult;  
   
        DBCon = new SqlConnection();  
        DBCon.ConnectionString = ConfigurationManger.ConnectionStrings["AspNetProvider"];  
   
        Command.CommandText = "SELECT TOP 5 Customers.*,Orders.* FROM Orders,Customers WHERE Orders.CustomerID = Customers.CustomerID ORDER BY ustomers.CompanyName";  
   
        Command.CommandType = CommandType.Text;  
        Command.Connection = DBCon;  
   
        DBCon.Open();  
   
        AsyncResult = Command.BeginExecuteReader();  
   
        while(!AsyncResult.IsCompleted)  
        {  
            System.Threading.Thread.Sleep(10);  
        }  
   
        OrderReader = Command.EndExecuteReader(AsyncResult);  
   
        // To do Anything You Want  
   
        DBCon.Close();  
    }  
} 

它首先调用BeginExecuteReader,启动异步进程。之后,使用while循环等待进程的完成。在等待时,主线程全检查异步进程的状态,然后休眠10毫秒。进程完成后,就使用EndExecuteReader方法提取结果。

如果在while循环上设置一个断点,就可以看到代码在调用BeiginExecuteReader方法后会继续执行。之后代码继续循环,直到异步进程完成为止。

 

Wait方式
3种方式中最好的一种不是Poll方式,也不是回调方式,而是Wait方式。该方式提供的灵活性最大、效率最高,但有点复杂。使用这种方式,可以编写代码,启动多个异步进程,等待全部或部分进程的完成。这种方式允许只等待互相依赖的进程,然后继续执行不互相依赖的进程。按照其设计,这种方式需要仔细考虑异步进程。必须认真选择出以并行方式运行的异步进程,最重要的是,确定不同的进程如何相互依赖。这种方式的复杂性在于,需要理解其中的细节,并设计出相应的代码。最终结果一般是,非常简洁的代码设计能最大限度地利用同步和异步处理模型。

using System.Data;
using System.Data.SqlClient;
using System.Data.Configuration;

public class SampleClass
{
    protected void Page_Load(object sender,EventArgs e)
    {
        SqlConnection DBCon;
        SqlCommand Command = new SqlCommand();
        SqlDataReader OrdersReader;
        IAsyncResult AsyncResult;

        System.Threading.WaitHandle WHandle;

        DBCon = new SqlConnection();
        DB.ConnectionStrings = ConfigurationManager.ConnectionStrings["AspNetProvider"];

        Command.CommandText = "SELECT TOP 5 Customers.*,Orders.* FROM Orders,Customers WHERE Orders.CustomerID = Customers.CustomerID ORDER BY ustomers.CompanyName";

        Command.CommandType = CommandType.Text;
        Command.Connection = DBCon;

        DBCon.Open();

        AsyncResult = Command.BeginExecuteReader();

        WHandle = AsyncResult.AsyncWaitHandle;

        if(WHandle.WaitOne() == true)
        {
            OrdersReader = Command.EndExecuteReader(AsyncResult);

            // Todo:

            DBCon.Close();
        }
        else
        {
            // When Execute On Timeouts EventHandler
        }
    }
}

如果设置一个断点,单步执行这段代码,程序就会在WHandle.WaitOne方法调用处停止执行。在异步进程完成后,程序会自动恢复执行。


回调方式
它首先调用BeginExecuteReader方法,给它传送回调委托,以启动异步进程。不需要进一步的处理,该方法在异步进程启动后结束。触发回调委托,以启动异步进程。不需要进一步的处理,该方法在异步进程启动后结束。

public class SampleClass
{
    protected void Page_Load(object sender,EventArgs e)
    {
        SqlConnection DBCon;
        SqlCommand Command = new SqlCommand();
        SqlDataReader OrdersReader;
        IAsyncResult AsyncResult;

        DBCon = new SqlConnection();
        DB.ConnectionStrings = ConfigurationManager.ConnectionStrings["AspNetProvider"];

        Command.CommandText = "SELECT TOP 5 Customers.*,Orders.* FROM Orders,Customers WHERE Orders.CustomerID = Customers.CustomerID ORDER BY ustomers.CompanyName";

        Command.CommandType = CommandType.Text;
        Command.Connection = DBCon;

        DBCon.Open();

        AsyncResult = Command.BeginExecuteReader(new AsyncCallback(CBMethod),CommandBehavior.CloseConnection);
    }

    public void CBMethod(SQLAsyncResult ar)
    {
        SqlDataReader OrdersReader;;

        OrdersReader = ar.EndExecuteReader(ar);

        // Todo:
    }
}

回调方式可以在代码的另一个部分处理命令执行的结果。当命令执行的时间比较长,且需要在不待到命令执行完毕后就回应用户时,可以使用这种方式。

取消异步处理
异步进程需要的时间常常比希望的长。为了避免这个问题,可以给用户提供一个选项来取消该进程,而不等待结果。取消异步进程只需在相应的Command对象上调用Cancel方法即可。这个方法没有返回值。为了回退已由Command对象完成的工作,必须在执行查询前,给Command对象提供一个定制事务。也可以自己处理回退或提交进程。

posted on 2010-07-10 12:29  xiaochao2012  阅读(671)  评论(0编辑  收藏  举报