可以用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对象提供一个定制事务。也可以自己处理回退或提交进程。